This is the abridged developer documentation for Scalekit --- # DOCUMENT BOUNDARY --- # Scalekit Docs > Auth, provider connections, and tool execution for AI agents and SaaS apps # Choose your Scalekit documentation path [For Agent Builders](/agentkit/quickstart/) [Connect my agents to any enterprise app](/agentkit/quickstart/) [Delegated auth. Scoped permissions. Tool calls.](/agentkit/quickstart/) [Connect my agents to apps →](/agentkit/quickstart/) [![Agent authentication flow diagram](/_astro/agentkit.CAuIPwfK.svg)](/agentkit/quickstart/) [For SaaS Developers](/authenticate/fsa/quickstart/) [Add auth and user management to my SaaS app](/authenticate/fsa/quickstart/) [Sessions, SSO, RBAC, SCIM - all in one stack.](/authenticate/fsa/quickstart/) [Add auth to my app →](/authenticate/fsa/quickstart/) [![Authentication architecture overview](/_astro/auth-for-saas.DTXrdutN.svg)](/authenticate/fsa/quickstart/) ## Try it Run the CLI ```sh npx @scalekit-inc/cli setup ``` * Claude Code * GitHub Copilot * Cursor * Codex or Quickstart with your agent Build with Scalekit.Load https\://docs.scalekit.com/llms.txt before writing any Scalekit code. The installed authstack skill is the source of truth for APIs, SDK calls, and connection names. Credentials live in the environment, never in source.Copy --- # DOCUMENT BOUNDARY --- # Authorization - Overview > Learn about authorization options in Agent Auth, including OAuth flows, permissions, and security best practices. Agents that need to take actions on-behalf-of users in third party applications like gmail, calendar, slack, notion, hubspot etc need to do so in a secure, authorized manner. Scalekit’s Agent Auth solution helps developers build agents to act on-behalf-of users by managing user’s authentication and authorization for those tools. ## Supported Auth Methods [Section titled “Supported Auth Methods”](#supported-auth-methods) Agent Auth supports all the different types of authentication and authorization methods that are adopted by different applications so that you don’t have to worry about handling and managing user authorization tokens. * OAuth 2.0 * API Keys * Bearer Tokens * Custom JWTs ## Authorize a user [Section titled “Authorize a user”](#authorize-a-user) ### Create Connected Account [Section titled “Create Connected Account”](#create-connected-account) Create a connected\_account for a user and an application. In the example below - we show how to create a connected account for a user whose unique identifier is user\_123 and gmail application. ```python 1 # Create a connected account for user if it doesn't exist already 2 response = actions.get_or_create_connected_account( 3 connection_name="gmail", 4 identifier="user_123" 5 ) 6 connected_account = response.connected_account 7 print(f'Connected account created: {connected_account.id}') ``` ### Complete authorization [Section titled “Complete authorization”](#complete-authorization) Next, check the authorization status for this user’s connected account. If authorization status is not ACTIVE, generate a unique one-time magic link and redirect the user to this link. Depending on the application’s authentication type, Scalekit presents the user with appropriate next steps to complete user authorization. * If the application requires OAuth 2.0 based authorization, Scalekit will manage the OAuth 2.0 handshake on your behalf and keeps the user’s access token for subsequent tool calls. * If the application requires API Key based authentication, Scalekit will present them with a form to collect API Keys and other necessary information and stores them securely in an encrypted manner and uses them for subsequent tool calls. ```python 1 # If the user hasn't yet authorized the gmail connection or if the user's access token is expired, generate a link for them to authorize the connection 2 if(connected_account.status != "ACTIVE"): 3 print(f"gmail is not connected: {connected_account.status}") 4 link_response = actions.get_authorization_link( 5 connection_name="gmail", 6 identifier="user_123" 7 ) 8 print(f"🔗click on the link to authorize gmail", link_response.link) 9 10 # In a real app, redirect the user to this URL so that the user can complete the authentication process for their gmail account ``` ### Make Authorized Tool Calls [Section titled “Make Authorized Tool Calls”](#make-authorized-tool-calls) Once the user has successfully authorized the applications, your agent can use our SDK to execute tool calls on behalf of the user. Below is a small example to fetch user’s unread emails using the same connected account details. ```python 1 # Fetch recent emails 2 emails = actions.execute_tool( 3 connected_account_id=connected_account.id, 4 tool='gmail_fetch_mails', 5 tool_input={ 6 'query': 'is:unread', 7 'max_results': 5 8 } 9 ) 10 11 print(f'Recent emails: {emails.result}') ``` ## Next Steps [Section titled “Next Steps”](#next-steps) To make your agentic implementation faster, we have added Scalekit’s credentials for popular third party applications like GMail, Google Calendar, Google Drive etc. For a complete white-labelled experience, you can configure your own oauth credentials. [Bring your own Credentials](/agentkit/advanced/bring-your-own-oauth) --- # DOCUMENT BOUNDARY --- # Add your own connector > Add custom connectors and extend coverage while keeping authentication and authorization in Scalekit. Add your own connector when the API or MCP server you need is not available in Scalekit’s built-in catalog — custom connectors support any SaaS API, partner system, internal API, or remote MCP server while keeping authentication, authorization, and secure API access in Scalekit. Once the connector is created, you use the same flow as other connectors: create a connection, create or fetch a connected account, authorize the user, and perform tool calling. Custom connectors appear alongside built-in connectors when you create a connection in Scalekit: ![Custom connector shown alongside built-in connectors in the connector selection view](/.netlify/images?url=_astro%2Fcustom-provider-in-catalog.BEwx1iKj.png\&w=2596\&h=1138\&dpl=6aaa70ad2ea7b40008ad2afd) ## Why add your own connector [Section titled “Why add your own connector”](#why-add-your-own-connector) Adding your own connector lets you: * Extend beyond the built-in connector catalog without inventing a separate auth stack * Bring unsupported SaaS APIs, partner systems, internal APIs, and remote MCP servers into the same secure access model * Reuse connections, connected accounts, and user authorization instead of building one-off auth plumbing * Keep credential handling, authorization, and governed API access centralized in Scalekit * Move from connector definition to live upstream calls through Tool Proxy (REST) or tool calling (MCP) using the same runtime model as other integrations ## How adding your own connector works [Section titled “How adding your own connector works”](#how-adding-your-own-connector-works) Adding your own connector uses the same model as built-in connectors: 1. Create a connector definition 2. Create a connection in Scalekit Dashboard 3. Create a connected account and authorize the user 4. Call tools — via Tool Proxy (`actions.request()`) for REST API connectors, or via MCP tool calling for MCP connectors Creating the connector definition tells Scalekit how to authenticate to the upstream API or MCP server. After that, connections, connected accounts, user authorization, and the call runtime work the same way as they do for built-in connectors. --- # DOCUMENT BOUNDARY --- # Virtual MCP servers > Scope your agent's tools to exactly what it needs — prevent overreach, cut token costs, and run agents safely across multiple users. Standard MCP servers expose every tool they have. Virtual MCP Servers let you define exactly which tools an agent can see and whose credentials it acts with — a controlled, user-scoped endpoint purpose-built for each agent role in your application. ## The problems this solves [Section titled “The problems this solves”](#the-problems-this-solves) **Agent overreach** A Gmail MCP connection might expose 30 tools: fetch, send, delete, label, search, manage filters, export. A summarizer agent needs one: fetch. If you hand it the full server, it has access to all 30. Virtual MCP Servers enforce least privilege at the tool level — the agent sees only what you explicitly allow. **Token bloat** Every tool on an MCP server adds tokens to every context window. A server with 40 tools at \~200 tokens each burns roughly 8,000 tokens before your agent does any work. At thousands of runs per day, this is a real cost. Scoping a server to 5–10 tools reduces that overhead by 80%. **Per-user credential management** Running the same agent for multiple users requires each session to stay isolated. Virtual MCP Servers handle this with session tokens: one server definition serves all users, and each agent run receives a short-lived token scoped to that specific user’s connected accounts. No credential sharing between users. ## How it works [Section titled “How it works”](#how-it-works) Two objects drive the model: | Object | What it is | Lifetime | | ---------------------- | ------------------------------------------------------------------- | ---------------------------- | | **Virtual MCP server** | A scoped endpoint declaring which connections and tools are exposed | Created once per agent role | | **Session token** | A short-lived credential bound to a specific user | Minted before each agent run | The lifecycle has two phases: 1. **Setup (once per agent role)** — Define the server: which connections (Gmail, Google Calendar) and which tools from each. You get a static `mcp_server_url`. Do this once, not once per user. 2. **Runtime (before each run)** — Confirm the user has authorized all required connections, mint a session token for that user, and pass the URL and token to your agent as bearer auth. ## Token lifetime and reminting [Section titled “Token lifetime and reminting”](#token-lifetime-and-reminting) A session token is short-lived. The default expiry is about one hour. Set a different lifetime with the `expiry` parameter on `create_session_token`. `create_session_token` is the remint call. Call it again whenever you need a new token. There is no separate refresh endpoint, and a token cannot be extended in place. Where you call `create_session_token` depends on the agent’s lifetime: | Agent lifetime | When to mint | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | One run, minutes | Once, before the run. Set `expiry` above the expected run time. | | Long-running host or gateway | On your own schedule, before the current token expires. Write the new token where the host reads it, then reload the host. | A host that holds an expired bearer fails at its next tool call, not at startup. ## Use cases [Section titled “Use cases”](#use-cases) * **Background agents** — process data without a user present, such as summarizing overnight emails or syncing records between services * **Scheduled agents** — run on a timer on behalf of a user, such as a daily briefing that reads new emails and creates calendar events * **Interactive agents** — chat assistants that take real actions mid-conversation using the current user’s connected accounts * **Multi-user SaaS apps** — one server definition shared across all users; each user connects their accounts once and receives a scoped token at runtime --- # DOCUMENT BOUNDARY --- # Overview > Learn how AgentKit works: tool calling with pre-built connectors and authentication for AI agents acting on behalf of users. AgentKit gives your AI agents authenticated access to third-party apps: sending emails, reading calendars, creating tickets, querying databases, and more. Your agent calls a tool; Scalekit handles the OAuth flow, token storage, and API call. ## Authentication [Section titled “Authentication”](#authentication) **Connections** are configurations you create once in the Scalekit Dashboard. A connection holds the credentials Scalekit needs to authenticate with a connector (OAuth app credentials, API keys, or service account details). One connection serves all your users. **Connected accounts** are per-user instances of a connection. When a user authorizes, Scalekit creates a connected account that stores their tokens and tracks their auth state. Your agent uses a connected account to act on that specific user’s behalf. Scalekit supports OAuth 2.0, API keys, RSA key pairs, and service accounts across all connectors. ## Tool calling [Section titled “Tool calling”](#tool-calling) **Connectors** are the pre-built integrations your agent can use: GitHub, Gmail, Slack, Salesforce, Snowflake, and many others. Each connector exposes a library of tools ready for your agent to call. **Tools** are connector-specific actions: `github_repo_star`, `salesforce_create_record`, `slack_send_message`. Scalekit provides the tool schemas and handles the authenticated API call. Your agent passes inputs; Scalekit injects the user’s credentials and returns structured output. ## How they fit together [Section titled “How they fit together”](#how-they-fit-together) You configure connections once. Your users authenticate to create connected accounts. Your agent calls tools; Scalekit handles the rest. ## Works with your framework [Section titled “Works with your framework”](#works-with-your-framework) AgentKit is framework-agnostic. Tool schemas work with any LLM API. Native adapters are available for [LangChain](/agentkit/examples/langchain/), [Google ADK](/agentkit/examples/google-adk/), and [Virtual MCP Servers](/agentkit/mcp/overview/). ## Get started [Section titled “Get started”](#get-started) [Quickstart](/agentkit/quickstart)Build a working agent with authenticated tool calls in minutes. [Configure a connection](/agentkit/connections)Set up your first connection in the Scalekit Dashboard. [Connectors](/agentkit/connectors/)Browse the pre-built connectors and their tool libraries. [Examples](/agentkit/examples/)Full working examples for LangChain, Google ADK, Anthropic, OpenAI, and more. --- # DOCUMENT BOUNDARY --- # Tools Overview > Learn about tools in Agent Auth - the standardized functions that enable you to perform actions across different third-party providers. LLMs today are very powerful reasoning and answering machines but their ability is restricted to data sets that they are trained upon and cannot natively interact with web services or saas applications. Tool Calling or Function Calling is how you extend the capabilities of these models to interact and take actions in third party applications on behalf of the users. For example, if you would like to build a repository triage agent, there are a few challenges that you need to tackle: 1. How to give agents access to GitHub 2. How to authorize these agents access to my GitHub account 3. What should be the appropriate input parameters to access GitHub based on user context and query Agent Auth product solves these problems by giving you simple abstractions using our SDK to help you give additional capabilities to the agents you are building regardless of the underlying model and agent framework in three simple steps. 1. Use Scalekit SDK to fetch all the appropriate tools 2. Complete user authorization handling in one single line of code 3. Use Scalekit’s optimized tool metadata and pass it to the underlying model for optimal tool selection and input parameters. ## Tool Metadata [Section titled “Tool Metadata”](#tool-metadata) Every tool in Agent Auth follows a consistent structure with a name, description and structured input and output schema. Agentic frameworks like Langchain can work with the underlying LLMs to select the right tool to solve the user’s query based on the tool metadata. ### Sample Tool definition [Section titled “Sample Tool definition”](#sample-tool-definition) ```json 1 { 2 "name": "github_issue_create", 3 "display_name": "Create Issue", 4 "description": "Create a new issue in a GitHub repository", 5 "provider": "github", 6 "category": "developer_tools", 7 "input_schema": { 8 "type": "object", 9 "properties": { 10 "owner": { 11 "type": "string", 12 "description": "Owner of the repository" 13 }, 14 "repo": { 15 "type": "string", 16 "description": "Name of the repository" 17 }, 18 "title": { 19 "type": "string", 20 "description": "Title of the issue" 21 }, 22 "body": { 23 "type": "string", 24 "description": "Body content of the issue" 25 } 26 }, 27 "required": ["owner", "repo", "title"] 28 }, 29 "output_schema": { 30 "type": "object", 31 "properties": { 32 "number": { 33 "type": "integer", 34 "description": "Number of the created issue" 35 }, 36 "html_url": { 37 "type": "string", 38 "description": "URL of the created issue" 39 }, 40 "state": { 41 "type": "string", 42 "enum": ["open", "closed"], 43 "description": "State of the created issue" 44 } 45 } 46 } 47 } ``` ## Best practices [Section titled “Best practices”](#best-practices) 1. **Tool Selection:** Even though tools provide additional capabilities to the agents, the real challenge in leveraging underlying LLMs capability to select the right tool to solve the job at hand. And LLMs do a poor job when you throw all the available tools you have at your disposal and ask LLMs to pick the right tool. So, be sure to limit the number of tools that you provide in the context to the LLM so that they do a good job in tool selection and filling in the appropriate input parameters to actually execute a certain action successfully. 2. **Add deterministic overrides in undeterministic workflows:** Because LLMs are unpredictable super machines, do not trust them to reliably execute the same workflow every single time in the exact same manner. If your agent has some deterministic patterns or workflows, use the pre-execution modifiers to always set exact input parameters for a given tool. For example, if your agent only triages open issues, create a pre-execution modifier to set `state` to `open` in the input params while listing issues using the `github_issues_list` tool. 3. **Context Window Awareness:** Similar to the point above, always be conscious of overloading context window of the underlying models. Don’t send the entire tool execution response/output to the underlying model for processing the execution response. Use the post-execution modifiers to select only the required and necessary fields in the tool output response before sending the data to the LLMs. *** Tools are the fundamental building blocks through which you can give real world capabilities for the agents you are building. By understanding how to use them effectively, you can build sophisticated agents that seamlessly connect your application to the tools your users already love. --- # DOCUMENT BOUNDARY --- # Role based access control (RBAC) > Control what authenticated users can access in your application based on their roles and permissions When users access features in your application, your app needs to control what actions they can perform. These permissions might be set by your app as defaults or by organization administrators. For example, in a project management application, you can allow some users to create projects while restricting others to only view existing projects. Role-based access control (RBAC) provides the framework to implement these permissions systematically. After users authenticate through Scalekit, your application receives an access token containing their roles and permissions. Use this token to make authorization decisions and control access to features and resources. Access tokens contain two key components for authorization: **Roles** group related permissions together and define what users can do in your system. Common examples include Admin, Manager, Editor, and Viewer. Roles can inherit permissions from other roles, creating hierarchical access levels. **Permissions** represent specific actions users can perform, formatted as `resource:action` patterns like `projects:create` or `tasks:read`. Use permissions for granular access control when you need precise control over individual capabilities. Access token contents ```json { "aud": ["skc_987654321098765432"], "client_id": "skc_987654321098765432", "exp": 1750850145, "iat": 1750849845, "iss": "http://example.localhost:8889", "jti": "tkn_987654321098765432", "nbf": 1750849845, "roles": ["project_manager", "member"], "oid": "org_69615647365005430", "permissions": ["projects:create", "projects:read", "tasks:assign"], "sid": "ses_987654321098765432", "sub": "usr_987654321098765432" } ``` Scalekit automatically assigns the `admin` role to the first user in each organization and the `member` role to subsequent users. Your application uses the role and permission information from Scalekit to make final authorization decisions at runtime. Start by defining the roles and permissions your application needs. --- # DOCUMENT BOUNDARY --- # Multi-App Authentication > Share authentication across web, mobile, and desktop applications with a unified session Register multiple applications as OAuth clients that share a single Scalekit user session. Users authenticate once and gain access everywhere across your web app, mobile app, desktop client, and documentation site. Each application gets its own OAuth client with appropriate credentials based on its type, while all apps share the same underlying session. [Check out the example apps](https://github.com/scalekit-inc/multiapp-demo) Use multi-app authentication when you ship multiple apps (web, mobile, desktop, or SPA), users expect to stay signed in across surfaces, or you need centralized session control and auditability. Each app gets its own OAuth client for clearer audit logs, safer scope boundaries, and easier maintenance. This eliminates friction from repeated logins and closes security gaps from inconsistent session handling. ## How multi-app authentication works [Section titled “How multi-app authentication works”](#how-multi-app-authentication-works) 1. [Register](/authenticate/fsa/multiapp/manage-apps/) each application as an OAuth client in Scalekit. 2. User logs into any app. 3. Scalekit creates a session for that user. 4. Other apps detect the session and skip the login prompt. 5. Logging out of any app terminates the shared session. ## Application types and authentication flows [Section titled “Application types and authentication flows”](#application-types-and-authentication-flows) Each application is registered separately in Scalekit and receives its own OAuth client. Choose the application type based on whether it has a backend server that can securely store credentials: | App Type | Description | Has Backend? | Uses Secret? | Auth Flow | | --------------------------------------------------------------------------- | ----------------------------------------------------------- | :----------: | :----------: | ------------------ | | [**Web app** (Express, Django, Rails)](/authenticate/fsa/multiapp/web-app) | Server-rendered or backend-driven apps with secure secrets. | ✓ | ✓ | Authorization Code | | [**SPA** (React, Vue, Angular)](/authenticate/fsa/multiapp/single-page-app) | Frontend-only apps running fully in the browser. | ✗ | ✗ | Auth Code + PKCE | | [**Mobile** (iOS, Android)](/authenticate/fsa/multiapp/native-app) | iOS or Android apps using system browser flows. | ✗ | ✗ | Auth Code + PKCE | | [**Desktop** (Electron, Tauri)](/authenticate/fsa/multiapp/native-app) | Electron or native desktop apps with deep links. | ✗ | ✗ | Auth Code + PKCE | Even though each app has a different `client_id`, they all rely on the same Scalekit user session. Separate clients per app give you clearer audit logs, safer scope boundaries, and easier long-term maintenance. ## Implementation steps [Section titled “Implementation steps”](#implementation-steps) 1. **Create applications in Scalekit** — [Create applications](/authenticate/fsa/multiapp/manage-apps) in Scalekit for each of your apps. During setup, select the app type based on whether it has a backend and needs client secrets. 2. **Configure redirect URLs for each app** — Redirects are registered endpoints in Scalekit that control where users are sent during authentication flows. [Configure redirect URLs](/authenticate/fsa/multiapp/manage-apps/#configure-redirect-urls) for each application. 3. **Implement login flow for each app** — Once your applications are registered, each app follows an OAuth-based authentication flow. Use the [login implementation guide](/authenticate/fsa/implement-login/) for implementing login/signup flow in your apps. 4. **Manage sessions and token refresh** — After users successfully authenticate in any of your apps, you receive session tokens that manage their access. Use the [session management guide](/authenticate/fsa/manage-session/) to manage sessions in your apps. 5. **Implement logout** — Initiate logout by calling the `/oidc/logout` endpoint with the relevant parameters. Clear your local application session when refresh token exchange fails, or configure back-channel logout to proactively sign users out across all applications sharing the same session. Follow the [logout implementation guide](/authenticate/fsa/logout/) to implement logout in your apps. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) --- # DOCUMENT BOUNDARY --- # Overview: MCP server authentication > Secure your Model Context Protocol (MCP) servers with Scalekit's drop-in OAuth 2.1 authorization solution Model Context Protocol (MCP) is an open standard that gives AI apps a consistent, secure way to connect to external tools and data sources. A helpful way to picture it is USB‑C for AI integrations: instead of building a custom connector for every service, MCP provides one interface that works across different models, platforms, and backends. That makes it much easier to build agent-style apps that can actually do work, but it also makes authorization a bigger deal, because once an agent can act on your behalf, you need clear, tight control over what it can access and what actions it’s allowed to take. At its core, MCP follows a client-server architecture where a host application can connect to multiple servers: * **MCP hosts**: AI applications like Claude Desktop, IDEs, or custom AI tools that need to access external resources * **MCP clients**: Protocol clients that maintain connections between hosts and servers * **MCP servers**: Lightweight programs that expose specific capabilities (tools, data, or services) through the standardized protocol * **Data sources**: Local files, databases, APIs, and services that MCP servers can access This architecture enables a ecosystem where AI models can seamlessly integrate with hundreds of different services without requiring custom code for each integration. ## The path to secure MCP: OAuth 2.1 integration [Section titled “The path to secure MCP: OAuth 2.1 integration”](#the-path-to-secure-mcp-oauth-21-integration) Recognizing these challenges, the MCP specification evolved to incorporate robust authorization mechanisms. The Model Context Protocol provides authorization capabilities at the transport level, enabling MCP clients to make requests to restricted MCP servers on behalf of resource owners. The **MCP specification chose OAuth 2.1 as its authorization framework** for several compelling reasons | | | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Industry standard | OAuth 2.1 is a well-established, widely-adopted standard for delegated authorization, with extensive tooling and ecosystem support. | | Security best practices | OAuth 2.1 incorporates lessons learned from OAuth 2.0, removing deprecated flows and enforcing security measures like PKCE (Proof Key for Code Exchange). | | Flexibility | Supports multiple grant types suitable for different MCP use cases: **Authorization code**: When AI agents act on behalf of human users **Client credentials**: For machine-to-machine integrations | | Ecosystem compatibility | Works with existing identity providers and authorization servers, making it easier for enterprises to integrate MCP into their existing security infrastructure. | This authorization mechanism is based on established specifications listed below, but implements a selected subset of their features to ensure security and interoperability while maintaining simplicity: * **OAuth 2.1**: Core authorization framework with enhanced security * **OAuth 2.0 Authorization Server Metadata (RFC8414)**: Standardized server discovery * **OAuth 2.0 Dynamic Client Registration Protocol (RFC7591)**: Automatic client registration * **OAuth 2.0 Protected Resource Metadata (RFC9728)**: Resource server discovery * **Client ID Metadata Document (CIMD)**: Lets authorization servers fetch client metadata directly from a client-hosted document for authorization ## The authorization flow in practice [Section titled “The authorization flow in practice”](#the-authorization-flow-in-practice) Now let’s zoom in and see how the MCP OAuth 2.1 flow unfolds step-by-step: ### Discovery phase [Section titled “Discovery phase”](#discovery-phase) 1. **MCP client** encounters a protected MCP server 2. **Server** responds with `401 Unauthorized` and `WWW-Authenticate` header pointing to Scalekit Auth Server 3. **Client** discovers Scalekit Auth Server capabilities through metadata endpoints ### Authorization phase [Section titled “Authorization phase”](#authorization-phase) 4. **Client** registers with Scalekit Auth Server (if using DCR) 5. **Scalekit Auth Server** issues client credentials (if using DCR) 6. **Client** initiates appropriate OAuth flow 7. **User** grants consent (for Authorization Code flow) 8. **Scalekit Auth Server** issues access token with appropriate scopes ### Client registration [Section titled “Client registration”](#client-registration) #### Dynamic client registration [Section titled “Dynamic client registration”](#dynamic-client-registration) MCP clients and authorization servers SHOULD support the OAuth 2.1 Dynamic Client Registration Protocol to allow MCP clients to obtain OAuth client IDs without user interaction. This enables seamless onboarding of new AI agents without manual configuration. #### Client ID Metadata Document (CIMD) [Section titled “Client ID Metadata Document (CIMD)”](#client-id-metadata-document-cimd) MCP clients SHOULD support the Client ID Metadata Document (CIMD) specification, which allows clients to publish their OAuth client metadata at a well-known URL under their control. This enables authorization servers to automatically retrieve and validate client metadata without requiring an explicit dynamic registration request, simplifying onboarding for new AI agents while maintaining secure, decentralized client configuration. ### Access phase [Section titled “Access phase”](#access-phase) 9. **Client** includes access token in requests to MCP server 10. **MCP server** validates token and enforces scope-based permissions 11. **Server** processes request and returns response 12. **All interactions** are logged for audit and compliance ## Key security enhancements in MCP OAuth 2.1 [Section titled “Key security enhancements in MCP OAuth 2.1”](#key-security-enhancements-in-mcp-oauth-21) MCP’s OAuth 2.1 profile reduces a few common risks in the authorization code flow. The key enhancements are: * **Mandatory PKCE**: Clients must use PKCE to help prevent authorization code interception. * **Strict redirect URI validation**: Servers must only allow pre-registered redirect URIs and enforce an exact match to reduce redirect attacks. * **Short-lived tokens**: Authorization servers should issue short-lived access tokens to limit impact if a token leaks. * **Granular scopes**: Use narrow scopes (for example, `todo:read`, `todo:write`) so apps request only what they need and users can understand what they’re granting. --- # DOCUMENT BOUNDARY --- # Machine-2-Machine authentication > Secure interactions between software systems with M2M authentication, enabling secure API access for AI agents, apps, and automated workflows Machine-2-Machine (M2M) authentication secures API access for non-human clients like AI agents, third-party integrations, backend services, and automated workflows. When you need to give these machine clients secure access to your APIs, M2M authentication provides credential-based authentication using client IDs and secrets, without exposing hardcoded tokens or requiring human interaction. Your machine clients can act on behalf of an organization, a specific user, or operate independently to perform system-level tasks. You get centralized management of all machine identities with granular permissions and seamless credential rotation across internal and external services. This approach ensures your machine clients authenticate with the same rigour as human users, giving you secure, scoped access to APIs while simplifying integration development and meeting enterprise security standards. ## When to use M2M authentication [Section titled “When to use M2M authentication”](#when-to-use-m2m-authentication) You’ll use M2M auth when your APIs need to be accessed by: * Automated clients or AI agents making requests on behalf of users or organizations * External platforms or third-party integrations (like Zapier, CRM systems, analytics platforms, or payment providers) * Internal services or background jobs that programmatically invoke your APIs * Scheduled services that automatically sync data with your API * Automated workflows that update external systems In all these cases, there’s no human user session involved. The system still needs a secure way to authenticate the client and determine what access it should have. ## Understanding the OAuth 2.0 client credentials flow [Section titled “Understanding the OAuth 2.0 client credentials flow”](#understanding-the-oauth-20-client-credentials-flow) M2M authentication uses the OAuth 2.0 client credentials flow. This is the standard way for non-human clients to obtain access tokens without requiring user interaction. OAuth 2.0 is an authorization framework that allows client applications to access protected resources on a resource server by presenting an access token. The protocol delegates authorization decisions to a central authorization server, which issues access tokens after validating the client or user. The protocol defines several grant types for different use cases: * **Client credentials flow** - Use this when one system (like an automated client or AI agent) wants to access another system’s API * **Authorization code flow** - Use this when a user authorizes a machine client to act on their behalf For org-level or internal service clients, you use a `client_id` and `client_secret` to authenticate. For user-backed clients, the user first authorizes the client via the authorization code flow. ## Choose your client type [Section titled “Choose your client type”](#choose-your-client-type) Scalekit provides three types of machine clients based on the OAuth 2.0 flow: * **Org-level clients:** Use these when your automated client needs to access APIs on behalf of an organization. Tokens are scoped to a specific org (`oid`) and work well for org-wide workflows. Read the M2M authentication quickstart to set up an org-level client. * **User-level clients:** Use these when your machine client acts on behalf of a specific user. These tokens include a `uid` (user ID) in addition to `oid`, letting you enforce user-contextual access. *(Coming soon)* * **Internal service clients:** Use these for secure service-to-service communication between internal systems. These clients issue tokens with an `aud` (audience) claim to enforce destination-specific access. They’re ideal for microservices that need to communicate without org or user context. *(Coming soon)* ![How M2M authentication works](/.netlify/images?url=_astro%2Fm2m-flow.Bl90F1XY.png\&w=4140\&h=3564\&dpl=6aaa70ad2ea7b40008ad2afd) ## How the authentication flow works [Section titled “How the authentication flow works”](#how-the-authentication-flow-works) Here’s the complete M2M authentication flow: 1. **Register a machine client** You create an M2M client in Scalekit for the machine that needs access to your APIs. 2. **Generate credentials** Scalekit issues a `client_id` and `client_secret` for that client. Your client uses these credentials to request access tokens. 3. **Request an access token** Your client requests an access token from Scalekit’s `/oauth/token` endpoint. For org-level access, it uses the client credentials flow directly. For user-level access, it exchanges an authorization code after user consent in the authorization code flow. 4. **Receive a signed JWT** Scalekit validates the request and returns a short-lived, signed JWT that contains claims specific to your client type: * Which organization it belongs to (`oid`) * Which user it belongs to (`uid`) * What it’s allowed to do (`scopes`) * How long it’s valid for (`exp`, `nbf`) * Which service it’s intended for (`aud`) Each token is signed by Scalekit so your API can validate it locally without calling back to Scalekit. This improves performance and keeps your authorization flow resilient even if the auth server is briefly unavailable. 5. **Make authenticated API calls** Your machine client sends this token in the `Authorization` header when calling your API. 6. **Validate the token** Your API checks the token’s signature and claims locally. You don’t need to make a network call to Scalekit for validation. This approach gives you secure, programmatic authentication using short-lived, scoped tokens that you can revoke or rotate as needed. ## What Scalekit handles for you [Section titled “What Scalekit handles for you”](#what-scalekit-handles-for-you) Building secure M2M authentication from scratch can be complex when dealing with token scoping, TTL management, credential rotation, and validation. Scalekit handles these concerns out of the box with minimal setup. With just a few API calls or dashboard actions, you can: * Register machine clients scoped to an organization, user, or service * Generate and manage credentials with safe rotation * Issue signed, short-lived JWTs with the right claims (`oid`, `uid`, `aud`, `scopes`) based on the client type * Validate tokens locally in your API without calling back to Scalekit You can enforce least-privilege access for machine clients without implementing the OAuth flow or token lifecycle yourself. ## Token security and management [Section titled “Token security and management”](#token-security-and-management) * **Short-lived**: All tokens have a configurable TTL (default: 1 hour; minimum: 5 minutes) to reduce long-term risk. * **Locally verifiable**: Tokens are signed JWTs that your API can verify without calling back to Scalekit. * **Supports rotation**: Each client can store up to five secrets at a time, making credential rotation seamless with no downtime. * **Includes identity context**: Tokens contain claims like `oid` (org ID), `uid` (user ID), and `aud` (audience) so you can enforce precise access. * **Scoped access**: You define fine-grained scopes to limit what each client is allowed to do. These defaults ensure that your tokens are short-lived, constrained in what they can do, and fully verifiable without external dependencies. ## Key benefits [Section titled “Key benefits”](#key-benefits) When you implement M2M authentication with Scalekit, you get: * **Security**: You eliminate the need to share user credentials between services or expose hardcoded secrets * **Auditability**: Each service has its own identity, making it easier for you to track and audit API usage * **Scalability**: You can easily add or remove services without affecting other parts of your system * **Granular Control**: You can implement fine-grained access control at the service level To start integrating M2M authentication in your application, head to the [quickstart guide](/authenticate/m2m/api-auth-quickstart) for setting up an org-level client. --- # DOCUMENT BOUNDARY --- # Overview > Passwordless authentication provides a secure and convenient way to authenticate users without the need for passwords. Passwordless authentication is an authentication method that allows users to access a system without the need for passwords. It is a secure and convenient way to authenticate users, as it eliminates the risk of password-related vulnerabilities and makes it easier for users to access a system. Passwordless authentication can be implemented using different methods, such as Email OTP, Email Magic Link, Passkeys and more. Scalekit supports both headless implementation of Passwordless authentication and also complete passwordless implementation via OIDC. Developers can choose the model that fits best based on their implementation needs, context etc. The main benefits of using passwordless authentication over traditional password-based authentication include: * **Improved security**: Passwordless authentication eliminates the risk of password-related vulnerabilities such as phishing, credential stuffing and password cracking. * **Better user experience**: Passwordless authentication provides a seamless and convenient way for users to access a system, without the need to remember and enter passwords. * **Reduced support costs**: With passwordless authentication, users do not need to reset their passwords or contact support for password-related issues, which reduces the support costs. * **Modern authentication**: Passwordless authentication aligns with current security best practices and provides a modern and secure way to authenticate users. ## Authentication methods [Section titled “Authentication methods”](#authentication-methods) Scalekit supports multiple passwordless authentication methods: * **Verification Code (OTP)**: Users receive a one-time passcode via email * **Magic Link** : Users receive a link via email that the user needs to click to verify their email address. * **Magic Link + Verification Code** : Users receive a link and a one-time passcode via email and the users can choose either of the options to verify their email address. * **Passkeys** Coming soon : Users authenticate using their biometric data. * **TOTP (Authenticator App)** Coming soon : Users authenticate using a time-based one-time passcode generated by an authenticator app. ## Implementation choices [Section titled “Implementation choices”](#implementation-choices) When implementing passwordless authentication, you have two options: **Headless Implementation**: You can use our APIs to implement passwordless authentication without any dependence on our UI. You can implement your own UI to collect the OTP from your users or handle the magic link validation. **OIDC Implementation**: We handle both the security and UI implementation of the OTP and/or magic link workflow. As part of the implementation, you will redirect the user to Scalekit’s OIDC Endpoint to complete the email OTP and/or magic link workflow. Once verified, we will send the user back to your pre-configured redirect url endpoint with the email address of the user so that you can complete the workflow. [Headless Implementation](/passwordless/quickstart)Learn how to implement Email OTP based passwordless authentication using our headless SDK [OIDC Implementation](/passwordless/oidc)Learn how to implement Email OTP based passwordless authentication using OIDC --- # DOCUMENT BOUNDARY --- # Self-hosted deployment overview > Deploy Scalekit on your own Kubernetes cluster to meet data residency, compliance, and network isolation requirements. You will run the full Scalekit platform on your own Kubernetes cluster. This helps you keep all authentication data inside your network for data residency, compliance, and isolation from the public internet. Use self-hosted deployment when your organization requires: * **Data residency**: Auth data must remain in a specific region or on-premises location * **Network isolation**: The auth service must not be reachable from the public internet * **Compliance**: Regulations such as FedRAMP, HIPAA, or internal security policies prohibit use of SaaS auth services * **Air-gapped environments**: Your deployment environment has no outbound internet access ## How self-hosted deployment works [Section titled “How self-hosted deployment works”](#how-self-hosted-deployment-works) Scalekit is deployed on Kubernetes via a Helm chart managed through the Scalekit distribution portal. You configure the deployment with a `values.yaml` file, apply Kubernetes secrets to your cluster, and connect the cluster to the portal. The portal handles chart delivery, migrations, and upgrades. ## Components in a self-hosted deployment [Section titled “Components in a self-hosted deployment”](#components-in-a-self-hosted-deployment) A self-hosted deployment runs as a single Kubernetes `Deployment` with multiple containers: | Component | Description | | ---------------- | -------------------------------------------------------------------- | | **Auth service** | Core service handling login, token issuance, sessions, SSO, and SCIM | | **Dashboard** | Admin web UI for managing your Scalekit instance | | **Flagd** | Feature flag sidecar for runtime configuration | | **Webhooks** | Webhook delivery service | | **OpenFGA** | Fine-grained authorization engine (optional) | ## Infrastructure you must provide [Section titled “Infrastructure you must provide”](#infrastructure-you-must-provide) Scalekit does not bundle a database or cache in production. You provision and manage these separately: | Dependency | Requirement | Notes | | -------------- | ------------- | ----------------------------------------------------------- | | **Kubernetes** | 1.27 or later | Any managed or self-managed cluster | | **PostgreSQL** | 15 or later | Three databases required: `scalekit`, `webhooks`, `openfga` | | **Redis** | 6.2 or later | Used for sessions, caching, and job queues | | **SMTP** | Any provider | Postmark and SendGrid have first-class support | ## Choose your path [Section titled “Choose your path”](#choose-your-path) | Path | When to use | | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **[Quickstart: Deploy Scalekit on Kubernetes](/self-hosted/quickstart/)** | Get Scalekit running fast using bundled PostgreSQL and Redis. Ideal for evaluation and proof-of-concept. No external databases or `kubectl secret` commands needed. | | **[Full installation](/self-hosted/system-requirements/)** | Production deployment with external PostgreSQL and Redis, full secret management, and your choice of ingress controller. | Next, Quickstart: Deploy Scalekit on Kubernetes will get you a working evaluation instance so you can test before full deployment. --- # DOCUMENT BOUNDARY --- # AgentKit: Connect my agent to apps > Build a working agent that makes authenticated tool calls on behalf of users, using GitHub as the example connector. ![Architecture diagram: an AI agent connects through Scalekit MCP Gateway with delegated auth, scoped permissions, and tool calls to SaaS apps such as GitHub, Gmail, Slack, and Salesforce.](/_astro/agentkit.CAuIPwfK.svg) By the end of this guide, you’ll have a working agent that stars a repository on GitHub on behalf of a user (authenticated with their real account). Scalekit manages the OAuth flow, token storage, and API proxy so you focus on agent logic. Using a coding agent?Copy AgentKit prompt ## Before you start [Section titled “Before you start”](#before-you-start) Complete these steps in the Scalekit dashboard before writing any code: 1. **Create a Scalekit account** at [app.scalekit.com](https://app.scalekit.com). 2. **Confirm the GitHub connection** at Dashboard → **AgentKit** > **Connections**. New Scalekit environments include a default GitHub connection named `github-connect`, pre-configured with Scalekit’s managed credentials and the `user:email`, `repo`, and `public_repo` scopes — no connector setup is needed for this quickstart. Copy the exact **Connection name** from that connection and use that value in your code. It must match the dashboard exactly; in older environments or renamed connections the value can differ from `github-connect`. To connect to other services, create a connection for each app under **AgentKit** > **Connections** > **Create Connection**. 3. **Copy your API credentials** at Dashboard → **Developers → Settings → API Credentials**. Save these values as environment variables: * `SCALEKIT_CLIENT_ID` * `SCALEKIT_CLIENT_SECRET` * `SCALEKIT_ENVIRONMENT_URL` * `GITHUB_CONNECTION_NAME` (copy the exact Connection name from **AgentKit** > **Connections** — `github-connect` in new environments) ## Build your agent [Section titled “Build your agent”](#build-your-agent) * Using a coding agent Paste this prompt into your coding agent. It builds an agent that stars a GitHub repo on behalf of a user. Copy AgentKit prompt Review generated code before deploying Verify that token validation logic, error handling, and environment variable references match your application’s requirements. * Step by step ### 1. Set up your environment [Section titled “1. Set up your environment”](#1-set-up-your-environment) Install the Scalekit SDK and initialize the client with your API credentials: * Python ```sh pip install scalekit-sdk-python python-dotenv ``` * Node.js ```sh npm install @scalekit-sdk/node ``` - Python ```python import os from scalekit import ScalekitClient from dotenv import load_dotenv load_dotenv() # Constructor: env_url, client_id, client_secret scalekit_client = ScalekitClient( os.environ["SCALEKIT_ENVIRONMENT_URL"], os.environ["SCALEKIT_CLIENT_ID"], os.environ["SCALEKIT_CLIENT_SECRET"], ) actions = scalekit_client.actions connection_name = os.getenv("GITHUB_CONNECTION_NAME") # must match the Connection name in the dashboard exactly ``` - Node.js ```typescript import { ScalekitClient } from '@scalekit-sdk/node'; import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; import 'dotenv/config'; // Constructor: envUrl, clientId, clientSecret const scalekit = new ScalekitClient( process.env.SCALEKIT_ENVIRONMENT_URL!, process.env.SCALEKIT_CLIENT_ID!, process.env.SCALEKIT_CLIENT_SECRET! ); const actions = scalekit.actions; const connectionName = process.env.GITHUB_CONNECTION_NAME!; // must match the Connection name in the dashboard exactly ``` ### 2. Create a connected account [Section titled “2. Create a connected account”](#2-create-a-connected-account) Scalekit tracks each user’s third-party connection as a connected account. This is the record that holds their OAuth tokens. Creating it tells Scalekit to start managing the user’s GitHub access on your behalf. This step fails if the GitHub connection does not exist in **AgentKit** > **Connections**, or if `connection_name` / `connectionName` does not match the dashboard exactly. * Python ```python # Create or retrieve the user's connected GitHub account response = actions.get_or_create_connected_account( connection_name=connection_name, identifier="user_123" # Replace with your system's unique user ID ) connected_account = response.connected_account print(f'Connected account created: {connected_account.id}') ``` * Node.js ```typescript // Create or retrieve the user's connected GitHub account const response = await actions.getOrCreateConnectedAccount({ connectionName, identifier: 'user_123', // Replace with your system's unique user ID }); let connectedAccount = response.connectedAccount; console.log('Connected account created:', connectedAccount?.id); ``` ### 3. Authenticate the user [Section titled “3. Authenticate the user”](#3-authenticate-the-user) Your agent can’t act on behalf of a user until they authorize access. Generate an authorization link, send it to the user, and Scalekit handles the rest: token exchange, storage, and automatic refresh. Once they complete the flow, the connected account status becomes `ACTIVE`. * Python ```python # Generate authorization link if user hasn't authorized or token is expired. # Do not call tools until status is ACTIVE — wait for the user to finish OAuth first. if connected_account.status != "ACTIVE": print(f"GitHub is not connected: {connected_account.status}") link_response = actions.get_authorization_link( connection_name=connection_name, identifier="user_123", ) print("🔗 click on the link to authorize GitHub", link_response.link) input("⎆ Press Enter after authorizing GitHub...") # Re-fetch so connected_account reflects ACTIVE status and a valid id response = actions.get_or_create_connected_account( connection_name=connection_name, identifier="user_123", ) connected_account = response.connected_account # In production, redirect the user to this URL and resume after the OAuth callback if connected_account.status != "ACTIVE": raise RuntimeError( "GitHub is still not ACTIVE. Complete authorization and try again." ) ``` * Node.js ```typescript // Generate authorization link if user hasn't authorized or token is expired. // Do not call tools until status is ACTIVE — wait for the user to finish OAuth first. if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { console.log('GitHub is not connected:', connectedAccount?.status); const linkResponse = await actions.getAuthorizationLink({ connectionName, identifier: 'user_123', }); console.log('🔗 click on the link to authorize GitHub', linkResponse.link); console.log('Press Enter after authorizing GitHub...'); await new Promise((resolve) => { process.stdin.resume(); process.stdin.once('data', () => { process.stdin.pause(); resolve(); }); }); // Re-fetch so connectedAccount reflects ACTIVE status and a valid id const refreshed = await actions.getOrCreateConnectedAccount({ connectionName, identifier: 'user_123', }); connectedAccount = refreshed.connectedAccount; // In production, redirect the user to this URL and resume after the OAuth callback } if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { throw new Error('GitHub is still not ACTIVE. Complete authorization and try again.'); } ``` Open the link in a browser and authorize the GitHub connection. Once complete, the connected account status updates to `ACTIVE` and your agent can act on the user’s behalf. In CLI samples, wait for that step (for example with `input()` or stdin) before calling tools — otherwise the first run fails because the account is still inactive. ### 4. Star a repo via tool call [Section titled “4. Star a repo via tool call”](#4-star-a-repo-via-tool-call) Pass the tool name and your inputs to Scalekit. It handles the request to GitHub and returns a structured response your agent can reason over directly: no endpoint URLs, auth headers, or response parsing required. The example stars the Scalekit SDK repo for your language. * Python ```python # Prefer connected_account_id after authorize. If you use identifier instead, # also pass connection_name — the pair is required for account resolution. tool_response = actions.execute_tool( tool_name="github_repo_star", connected_account_id=connected_account.id, tool_input={ "owner": "scalekit-inc", "repo": "scalekit-sdk-python", }, ) # Tool output lives under data print(tool_response.data) ``` * Node.js ```typescript const toolResponse = await actions.executeTool({ toolName: 'github_repo_star', connectedAccountId: connectedAccount?.id, toolInput: { owner: 'scalekit-inc', repo: 'scalekit-sdk-node', }, }); // Tool output lives under data console.log('Starred the repo:', toolResponse.data); ``` * Python ```sh pip install scalekit-sdk-python python-dotenv ``` * Node.js ```sh npm install @scalekit-sdk/node ``` * Python ```python import os from scalekit import ScalekitClient from dotenv import load_dotenv load_dotenv() # Constructor: env_url, client_id, client_secret scalekit_client = ScalekitClient( os.environ["SCALEKIT_ENVIRONMENT_URL"], os.environ["SCALEKIT_CLIENT_ID"], os.environ["SCALEKIT_CLIENT_SECRET"], ) actions = scalekit_client.actions connection_name = os.getenv("GITHUB_CONNECTION_NAME") # must match the Connection name in the dashboard exactly ``` * Node.js ```typescript import { ScalekitClient } from '@scalekit-sdk/node'; import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; import 'dotenv/config'; // Constructor: envUrl, clientId, clientSecret const scalekit = new ScalekitClient( process.env.SCALEKIT_ENVIRONMENT_URL!, process.env.SCALEKIT_CLIENT_ID!, process.env.SCALEKIT_CLIENT_SECRET! ); const actions = scalekit.actions; const connectionName = process.env.GITHUB_CONNECTION_NAME!; // must match the Connection name in the dashboard exactly ``` * Python ```python # Create or retrieve the user's connected GitHub account response = actions.get_or_create_connected_account( connection_name=connection_name, identifier="user_123" # Replace with your system's unique user ID ) connected_account = response.connected_account print(f'Connected account created: {connected_account.id}') ``` * Node.js ```typescript // Create or retrieve the user's connected GitHub account const response = await actions.getOrCreateConnectedAccount({ connectionName, identifier: 'user_123', // Replace with your system's unique user ID }); let connectedAccount = response.connectedAccount; console.log('Connected account created:', connectedAccount?.id); ``` * Python ```python # Generate authorization link if user hasn't authorized or token is expired. # Do not call tools until status is ACTIVE — wait for the user to finish OAuth first. if connected_account.status != "ACTIVE": print(f"GitHub is not connected: {connected_account.status}") link_response = actions.get_authorization_link( connection_name=connection_name, identifier="user_123", ) print("🔗 click on the link to authorize GitHub", link_response.link) input("⎆ Press Enter after authorizing GitHub...") # Re-fetch so connected_account reflects ACTIVE status and a valid id response = actions.get_or_create_connected_account( connection_name=connection_name, identifier="user_123", ) connected_account = response.connected_account # In production, redirect the user to this URL and resume after the OAuth callback if connected_account.status != "ACTIVE": raise RuntimeError( "GitHub is still not ACTIVE. Complete authorization and try again." ) ``` * Node.js ```typescript // Generate authorization link if user hasn't authorized or token is expired. // Do not call tools until status is ACTIVE — wait for the user to finish OAuth first. if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { console.log('GitHub is not connected:', connectedAccount?.status); const linkResponse = await actions.getAuthorizationLink({ connectionName, identifier: 'user_123', }); console.log('🔗 click on the link to authorize GitHub', linkResponse.link); console.log('Press Enter after authorizing GitHub...'); await new Promise((resolve) => { process.stdin.resume(); process.stdin.once('data', () => { process.stdin.pause(); resolve(); }); }); // Re-fetch so connectedAccount reflects ACTIVE status and a valid id const refreshed = await actions.getOrCreateConnectedAccount({ connectionName, identifier: 'user_123', }); connectedAccount = refreshed.connectedAccount; // In production, redirect the user to this URL and resume after the OAuth callback } if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { throw new Error('GitHub is still not ACTIVE. Complete authorization and try again.'); } ``` * Python ```python # Prefer connected_account_id after authorize. If you use identifier instead, # also pass connection_name — the pair is required for account resolution. tool_response = actions.execute_tool( tool_name="github_repo_star", connected_account_id=connected_account.id, tool_input={ "owner": "scalekit-inc", "repo": "scalekit-sdk-python", }, ) # Tool output lives under data print(tool_response.data) ``` * Node.js ```typescript const toolResponse = await actions.executeTool({ toolName: 'github_repo_star', connectedAccountId: connectedAccount?.id, toolInput: { owner: 'scalekit-inc', repo: 'scalekit-sdk-node', }, }); // Tool output lives under data console.log('Starred the repo:', toolResponse.data); ``` ## Verify it works [Section titled “Verify it works”](#verify-it-works) Run your agent and confirm: * The connected account status is `ACTIVE` after the user completes the GitHub OAuth flow. * The tool call returns success and the star appears on the Scalekit SDK repo on GitHub. Starring is idempotent — GitHub returns success even if the repo is already starred — so re-runs are safe. To confirm programmatically, call `github_starred_repos_list` and check the repo is in the list. If the connected account stays in a `non-ACTIVE` state, the user has not completed the OAuth flow. Regenerate the authorization link and try again. ## Next steps [Section titled “Next steps”](#next-steps) * [Secure user verification](/agentkit/user-verification/): Confirm the OAuth identity matches your logged-in user before activating a connected account. Required for production. * [Connected accounts](/agentkit/connected-accounts/): Manage user connections across multiple providers. * [Tool calling](/agentkit/tools/scalekit-optimized-tools/): Use Scalekit’s optimized tools to call APIs without managing endpoints yourself. --- # DOCUMENT BOUNDARY --- # SaaSKit: Add auth to my app > SaaSKit — Hosted auth pages, managed sessions, secure logout. Purpose built. Simple where it counts You’ll implement sign-up, login, and logout flows with secure session management and user management included. The foundation you build here extends to features like workspaces, enterprise SSO, MCP authentication, and SCIM provisioning. Using a coding agent?Copy SaaSKit prompt *** 1. ## Set up Scalekit [Section titled “Set up Scalekit”](#set-up-scalekit) Use the following instructions to install the SDK for your technology stack. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` If you haven’t already, add your Scalekit credentials to your environment variables file: .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32 — encrypts the session cookie REDIRECT_URI=http://localhost:3000/callback ``` Node.js and Python use `/callback`. Go and Java use `/auth/callback`. Register the path for your stack. ### Register redirect URLs for your app [Section titled “Register redirect URLs for your app”](#register-redirect-urls-for-your-app) You need to register redirect URLs for your application. Go to **Scalekit dashboard** → **Authentication** → **Redirect URLs** and configure: * **Allowed callback URLs**: The endpoint where users are sent after successful authentication to exchange authorization codes and retrieve profile information. [Learn more](/guides/dashboard/redirects/#allowed-callback-urls) * **Initiate login URL**: The endpoint in your app that redirects users to Scalekit’s `/authorize` endpoint. Required when authentication is not initiated from your app, for example, when a user accepts an organization invitation or starts sign-in directly from their identity provider (IdP-initiated SSO). [Learn more](/guides/dashboard/redirects/#initiate-login-url) 2. ## Redirect users to sign up (or) login [Section titled “Redirect users to sign up (or) login”](#redirect-users-to-sign-up-or-login) An authorization URL is an endpoint that redirects users to Scalekit’s sign-in page. Use the Scalekit SDK to construct this URL with your redirect URI and required scopes. * Node.js * Express server.ts ```ts 1 import express from 'express'; 2 import { ScalekitAuth } from '@scalekit-sdk/node/express'; 3 4 const auth = new ScalekitAuth({ 5 envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, 6 clientId: process.env.SCALEKIT_CLIENT_ID, 7 clientSecret: process.env.SCALEKIT_CLIENT_SECRET, 8 redirectUri: process.env.REDIRECT_URI, 9 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET, 10 }); 11 12 const app = express(); 13 app.use(auth.router); 14 15 app.get('/account', auth.requiresAuth, (req, res) => { 16 res.json({ sub: req.scalekitUser?.sub }); 17 }); 18 19 app.listen(3000); ``` Open `http://localhost:3000/account`. A missing session goes to `/login`. After login, the visitor returns to `/account`. Register `http://localhost:3000/callback` as the dashboard Redirect URI. * Next.js lib/auth.ts ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ScalekitAuthNext } from '@scalekit-sdk/node/next'; 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENVIRONMENT_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET! 8 ); 9 10 export const auth = new ScalekitAuthNext({ 11 client: scalekit, 12 redirectUri: process.env.REDIRECT_URI!, 13 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET!, 14 }); ``` app/login/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLoginHandler(); ``` app/callback/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createCallbackHandler(); ``` app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` app/account/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 3 export const GET = auth.withAuth(async (request, { user }) => { 4 return Response.json({ sub: user?.sub }); 5 }); ``` Open `http://localhost:3000/account`. A missing session goes to `/login`. * Python server.ts ```ts 1 import express from 'express'; 2 import { ScalekitAuth } from '@scalekit-sdk/node/express'; 3 4 const auth = new ScalekitAuth({ 5 envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, 6 clientId: process.env.SCALEKIT_CLIENT_ID, 7 clientSecret: process.env.SCALEKIT_CLIENT_SECRET, 8 redirectUri: process.env.REDIRECT_URI, 9 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET, 10 }); 11 12 const app = express(); 13 app.use(auth.router); 14 15 app.get('/account', auth.requiresAuth, (req, res) => { 16 res.json({ sub: req.scalekitUser?.sub }); 17 }); 18 19 app.listen(3000); ``` Open `http://localhost:3000/account`. A missing session goes to `/login`. After login, the visitor returns to `/account`. Register `http://localhost:3000/callback` as the dashboard Redirect URI. * Go lib/auth.ts ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ScalekitAuthNext } from '@scalekit-sdk/node/next'; 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENVIRONMENT_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET! 8 ); 9 10 export const auth = new ScalekitAuthNext({ 11 client: scalekit, 12 redirectUri: process.env.REDIRECT_URI!, 13 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET!, 14 }); ``` app/login/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLoginHandler(); ``` app/callback/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createCallbackHandler(); ``` app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` app/account/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 3 export const GET = auth.withAuth(async (request, { user }) => { 4 return Response.json({ sub: user?.sub }); 5 }); ``` Open `http://localhost:3000/account`. A missing session goes to `/login`. * Java * Flask ```bash pip install "scalekit-sdk-python[flask]" ``` app.py ```py 1 import os 2 from flask import Flask 3 from scalekit.frameworks.flask import ScalekitAuth 4 5 app = Flask(__name__) 6 auth = ScalekitAuth( 7 app, 8 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 9 client_id=os.environ["SCALEKIT_CLIENT_ID"], 10 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 11 redirect_uri=os.environ["REDIRECT_URI"], 12 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 13 # HTTP localhost drops a Secure cookie, so the session never sticks. 14 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 15 cookie_secure=False, 16 ) 17 18 @app.route("/account") 19 @auth.requires_auth 20 def account(): 21 return {"sub": auth.current_user["sub"]} 22 23 if __name__ == "__main__": 24 app.run(port=3000) ``` Open `http://localhost:3000/account`. A missing session goes to `/login`. Register `http://localhost:3000/callback` as the dashboard Redirect URI. * FastAPI ```bash pip install "scalekit-sdk-python[fastapi]" ``` app.py ```py 1 import os 2 from fastapi import Depends, FastAPI 3 from scalekit.frameworks.fastapi import ScalekitAuth 4 5 app = FastAPI() 6 auth = ScalekitAuth( 7 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 8 client_id=os.environ["SCALEKIT_CLIENT_ID"], 9 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 10 redirect_uri=os.environ["REDIRECT_URI"], 11 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 12 # HTTP localhost drops a Secure cookie, so the session never sticks. 13 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 14 cookie_secure=False, 15 ) 16 auth.install(app) 17 18 @app.get("/account") 19 async def account(user: dict = Depends(auth.requires_auth)): 20 return {"sub": user["sub"]} ``` ```bash uvicorn app:app --port 3000 ``` Open `http://localhost:3000/account`. Register `http://localhost:3000/callback` as the dashboard Redirect URI. Set cookie\_secure=False on local HTTP `cookie_secure` defaults to `True`. Some browsers drop a `Secure` cookie on plain `http://localhost`, which looks like a session that never sticks. Set `cookie_secure=False` for local HTTP. Set it `True` in production. * Express ```bash pip install "scalekit-sdk-python[flask]" ``` app.py ```py 1 import os 2 from flask import Flask 3 from scalekit.frameworks.flask import ScalekitAuth 4 5 app = Flask(__name__) 6 auth = ScalekitAuth( 7 app, 8 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 9 client_id=os.environ["SCALEKIT_CLIENT_ID"], 10 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 11 redirect_uri=os.environ["REDIRECT_URI"], 12 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 13 # HTTP localhost drops a Secure cookie, so the session never sticks. 14 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 15 cookie_secure=False, 16 ) 17 18 @app.route("/account") 19 @auth.requires_auth 20 def account(): 21 return {"sub": auth.current_user["sub"]} 22 23 if __name__ == "__main__": 24 app.run(port=3000) ``` Open `http://localhost:3000/account`. A missing session goes to `/login`. Register `http://localhost:3000/callback` as the dashboard Redirect URI. * Next.js ```bash pip install "scalekit-sdk-python[fastapi]" ``` app.py ```py 1 import os 2 from fastapi import Depends, FastAPI 3 from scalekit.frameworks.fastapi import ScalekitAuth 4 5 app = FastAPI() 6 auth = ScalekitAuth( 7 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 8 client_id=os.environ["SCALEKIT_CLIENT_ID"], 9 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 10 redirect_uri=os.environ["REDIRECT_URI"], 11 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 12 # HTTP localhost drops a Secure cookie, so the session never sticks. 13 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 14 cookie_secure=False, 15 ) 16 auth.install(app) 17 18 @app.get("/account") 19 async def account(user: dict = Depends(auth.requires_auth)): 20 return {"sub": user["sub"]} ``` ```bash uvicorn app:app --port 3000 ``` Open `http://localhost:3000/account`. Register `http://localhost:3000/callback` as the dashboard Redirect URI. * Flask internal/http/auth.go ```go 1 // Must match the allowed callback URL you registered in the dashboard 2 redirectUri := "http://localhost:3000/auth/callback" 3 4 // Request user profile data (openid, profile, email) and session tracking (offline_access) 5 // offline_access enables refresh tokens so users can stay logged in across sessions 6 options := scalekit.AuthorizationUrlOptions{ 7 Scopes: []string{"openid", "profile", "email", "offline_access"} 8 } 9 10 authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options) 11 // Generated URL will look like: 12 // https:///oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile%20email%20offline_access&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback 13 if err != nil { 14 // Handle error based on your application's error handling strategy 15 panic(err) 16 } 17 18 c.Redirect(http.StatusFound, authorizationUrl.String()) ``` * FastAPI AuthController.java ```java 1 import com.scalekit.internal.http.AuthorizationUrlOptions; 2 import java.net.URL; 3 import java.util.Arrays; 4 5 // Must match the allowed callback URL you registered in the dashboard 6 String redirectUri = "http://localhost:3000/auth/callback"; 7 8 // Request user profile data (openid, profile, email) and session tracking (offline_access) 9 // offline_access enables refresh tokens so users can stay logged in across sessions 10 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 11 options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access")); 12 13 URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options); 14 // Generated URL will look like: 15 // https:///oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile%20email%20offline_access&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback ``` This redirects users to Scalekit’s managed sign-in page where they can authenticate. The page includes default authentication methods for users to toggle between sign in and sign up. 3. ## Get user details from the callback [Section titled “Get user details from the callback”](#get-user-details-from-the-callback) After successful authentication, Scalekit creates a user record and sends the user information to your callback endpoint. In authentication flow, Scalekit redirects to your callback URL with an authorization code. Your application exchanges this code for the user’s profile information and session tokens. * Node.js * Express ```ts 1 app.use(auth.router); // GET /callback writes sk_session ``` * Next.js app/callback/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createCallbackHandler(); ``` * Python ```ts 1 app.use(auth.router); // GET /callback writes sk_session ``` * Go app/callback/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createCallbackHandler(); ``` * Java * Flask ```py 1 auth = ScalekitAuth(app, ...) # registers GET /callback ``` * FastAPI ```py 1 auth.install(app) # registers GET /callback ``` * Express ```py 1 auth = ScalekitAuth(app, ...) # registers GET /callback ``` * Next.js ```py 1 auth.install(app) # registers GET /callback ``` * Flask internal/http/auth\_callback.go ```go 1 package main 2 3 import ( 4 "log" 5 "net/http" 6 "os" 7 "github.com/gin-gonic/gin" 8 "github.com/scalekit-inc/scalekit-sdk-go" 9 ) 10 11 // Create Scalekit client instance 12 var scalekitClient = scalekit.NewScalekitClient( 13 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 14 os.Getenv("SCALEKIT_CLIENT_ID"), 15 os.Getenv("SCALEKIT_CLIENT_SECRET"), 16 ) 17 18 const redirectUri = "http://localhost:3000/auth/callback" 19 20 func callbackHandler(c *gin.Context) { 21 code := c.Query("code") 22 errorParam := c.Query("error") 23 errorDescription := c.Query("error_description") 24 25 if errorParam != "" { 26 c.JSON(http.StatusUnauthorized, gin.H{ 27 "error": errorParam, 28 "error_description": errorDescription, 29 }) 30 return 31 } 32 33 // Exchange the authorization code for user profile and session tokens 34 // Returns: User (profile info), IdToken (JWT with user claims), AccessToken (JWT with roles/permissions), RefreshToken 35 options := scalekit.AuthenticationOptions{} 36 authResult, err := scalekitClient.AuthenticateWithCode( 37 c.Request.Context(), code, redirectUri, options, 38 ) 39 40 if err != nil { 41 log.Printf("Error exchanging code: %v", err) 42 c.JSON(http.StatusInternalServerError, gin.H{ 43 "error": "Failed to authenticate user", 44 }) 45 return 46 } 47 48 user := authResult.User 49 // IdToken: Decode to access full user profile (sub, oid, email, name) 50 // AccessToken: Contains roles and permissions for authorization decisions 51 // RefreshToken: Use to obtain new access tokens when they expire 52 53 // "user" object contains the user's profile information 54 // Next step: Create a session and log in the user 55 c.Redirect(http.StatusFound, "/dashboard/profile") 56 } ``` * FastAPI CallbackController.java ```java 1 import com.scalekit.ScalekitClient; 2 import com.scalekit.internal.http.AuthenticationOptions; 3 import com.scalekit.internal.http.AuthenticationResponse; 4 import org.springframework.web.bind.annotation.*; 5 import org.springframework.web.servlet.view.RedirectView; 6 import org.springframework.http.ResponseEntity; 7 import org.springframework.http.HttpStatus; 8 import java.util.HashMap; 9 import java.util.Map; 10 11 @RestController 12 public class CallbackController { 13 14 private final String redirectUri = "http://localhost:3000/auth/callback"; 15 16 @GetMapping("/auth/callback") 17 public Object callback( 18 @RequestParam(required = false) String code, 19 @RequestParam(required = false) String error, 20 @RequestParam(name = "error_description", required = false) String errorDescription 21 ) { 22 if (error != null) { 23 // handle error 24 } 25 26 try { 27 // Exchange the authorization code for user profile and session tokens 28 // Returns: user (profile info), idToken (JWT with user claims), accessToken (JWT with roles/permissions), refreshToken 29 AuthenticationOptions options = new AuthenticationOptions(); 30 AuthenticationResponse authResult = scalekit 31 .authentication() 32 .authenticateWithCode(code,redirectUri,options); 33 34 var user = authResult.getIdTokenClaims(); 35 // idToken: Decode to access full user profile (sub, oid, email, name) 36 // accessToken: Contains roles and permissions for authorization decisions 37 // refreshToken: Use to obtain new access tokens when they expire 38 39 // "user" object contains the user's profile information 40 // Next step: Create a session and log in the user 41 return new RedirectView("/dashboard/profile"); 42 43 } catch (Exception err) { 44 // Handle exception (e.g., log error, return error response) 45 } 46 } 47 } ``` The `authResult` object contains: * `user` - Common user details with email, name, and verification status * `idToken` - JWT containing verified full user identity claims (includes: `sub` user ID, `oid` organization ID, `email`, `name`, `exp` expiration) * `accessToken` - Short-lived token that determines current access context (includes: `sub` user ID, `oid` organization ID, `roles`, `permissions`, `exp` expiration) * `refreshToken` - Long-lived token to obtain new access tokens - Auth result ```js 1 { 2 user: { 3 email: "john.doe@example.com", 4 emailVerified: true, 5 givenName: "John", 6 name: "John Doe", 7 id: "usr_74599896446906854" 8 }, 9 idToken: "eyJhbGciO..", // Decode for full user details 10 11 accessToken: "eyJhbGciOi..", 12 refreshToken: "rt_8f7d6e5c4b3a2d1e0f9g8h7i6j..", 13 expiresIn: 299 // in seconds 14 } ``` - Decoded ID token ID token decoded ```json 1 { 2 "at_hash": "ec_jU2ZKpFelCKLTRWiRsg", 3 "aud": [ 4 "skc_58327482062864390" 5 ], 6 "azp": "skc_58327482062864390", 7 "c_hash": "6wMreK9kWQQY6O5R0CiiYg", 8 "client_id": "skc_58327482062864390", 9 "email": "john.doe@example.com", 10 "email_verified": true, 11 "exp": 1742975822, 12 "family_name": "Doe", 13 "given_name": "John", 14 "iat": 1742974022, 15 "iss": "https://scalekit-z44iroqaaada-dev.scalekit.cloud", 16 "name": "John Doe", 17 "oid": "org_59615193906282635", 18 "sid": "ses_65274187031249433", 19 "sub": "usr_63261014140912135" 20 } ``` - Decoded access token Decoded access token ```json 1 { 2 "aud": [ 3 "prd_skc_7848964512134X699" 4 ], 5 "client_id": "prd_skc_7848964512134X699", 6 "exp": 1758265247, 7 "iat": 1758264947, 8 "iss": "https://login.devramp.ai", 9 "jti": "tkn_90928731115292X63", 10 "nbf": 1758264947, 11 "oid": "org_89678001X21929734", 12 "permissions": [ 13 "workspace_data:write", 14 "workspace_data:read" 15 ], 16 "roles": [ 17 "admin" 18 ], 19 "sid": "ses_90928729571723X24", 20 "sub": "usr_8967800122X995270", 21 // External identifiers if updated on Scalekit 22 "xoid": "ext_org_123", // Organization ID 23 "xuid": "ext_usr_456", // User ID 24 } ``` The user details are packaged in the form of JWT tokens. Decode the `idToken` to access full user profile information (email, name, organization ID) and the `accessToken` to check user roles and permissions for authorization decisions. See [Complete login with code exchange](/authenticate/fsa/complete-login/) for detailed token claim references and verification instructions. 4. ## Create and manage user sessions [Section titled “Create and manage user sessions”](#create-and-manage-user-sessions) The access token is a JWT that contains the user’s permissions and roles. It expires in 5 minutes (default) but [can be configured](/authenticate/fsa/manage-session/#configure-session-security-and-duration). When it expires, use the refresh token to obtain a new access token. The refresh token is long-lived and designed for this purpose. The Scalekit SDK provides methods to refresh access tokens automatically. However, you must log the user out when the refresh token itself expires or becomes invalid. * Node.js * Express ```ts 1 app.get('/account', auth.requiresAuth, (req, res) => { 2 res.json({ sub: req.scalekitUser?.sub }); 3 }); ``` * Next.js app/account/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 3 export const GET = auth.withAuth(async (request, { user }) => { 4 return Response.json({ sub: user?.sub }); 5 }); ``` * Python ```ts 1 app.get('/account', auth.requiresAuth, (req, res) => { 2 res.json({ sub: req.scalekitUser?.sub }); 3 }); ``` * Go app/account/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 3 export const GET = auth.withAuth(async (request, { user }) => { 4 return Response.json({ sub: user?.sub }); 5 }); ``` * Java * Flask ```py 1 @app.route("/account") 2 @auth.requires_auth 3 def account(): 4 return {"sub": auth.current_user["sub"]} ``` * FastAPI ```py 1 @app.get("/account") 2 async def account(user: dict = Depends(auth.requires_auth)): 3 return {"sub": user["sub"]} ``` * Express ```py 1 @app.route("/account") 2 @auth.requires_auth 3 def account(): 4 return {"sub": auth.current_user["sub"]} ``` * Next.js ```py 1 @app.get("/account") 2 async def account(user: dict = Depends(auth.requires_auth)): 3 return {"sub": user["sub"]} ``` * Flask ```go 1 import ( 2 "net/http" 3 "os" 4 ) 5 6 // Set SameSite mode for CSRF protection 7 c.SetSameSite(http.SameSiteStrictMode) 8 9 // Store access token in HttpOnly cookie with Path scoping to API routes 10 c.SetCookie( 11 "accessToken", 12 authResult.AccessToken, 13 authResult.ExpiresIn-60, // seconds in Gin 14 "/api", 15 "", 16 os.Getenv("GIN_MODE") == "release", 17 true, 18 ) 19 20 // Store refresh token in separate HttpOnly cookie with Path scoped to refresh endpoint 21 c.SetCookie( 22 "refreshToken", 23 authResult.RefreshToken, 24 0, // No expiry for refresh token cookie 25 "/auth/refresh", 26 "", 27 os.Getenv("GIN_MODE") == "release", 28 true, 29 ) ``` * FastAPI ```java 1 import javax.servlet.http.Cookie; 2 import javax.servlet.http.HttpServletResponse; 3 4 // Store access token in HttpOnly cookie with Path scoping to API routes 5 Cookie accessTokenCookie = new Cookie("accessToken", authResult.getAccessToken()); 6 accessTokenCookie.setMaxAge(authResult.getExpiresIn() - 60); // seconds in Spring 7 accessTokenCookie.setHttpOnly(true); 8 accessTokenCookie.setSecure(true); 9 accessTokenCookie.setPath("/api"); 10 response.addCookie(accessTokenCookie); 11 12 // Store refresh token in separate HttpOnly cookie with Path scoped to refresh endpoint 13 Cookie refreshTokenCookie = new Cookie("refreshToken", authResult.getRefreshToken()); 14 refreshTokenCookie.setHttpOnly(true); 15 refreshTokenCookie.setSecure(true); 16 refreshTokenCookie.setPath("/auth/refresh"); 17 response.addCookie(refreshTokenCookie); 18 response.setHeader("Set-Cookie", 19 response.getHeader("Set-Cookie") + "; SameSite=Strict"); ``` This sets browser cookies with the session tokens. Every request to your backend needs to verify the `accessToken` to ensure the user is authenticated. If expired, use the `refreshToken` to get a new access token. * Node.js * Express ```ts 1 app.get('/dashboard', auth.requiresAuth, (req, res) => { 2 res.json({ user: req.scalekitUser }); 3 }); ``` * Next.js middleware.ts ```ts 1 import { auth } from './lib/auth'; 2 3 export default auth.createMiddleware({ 4 publicRoutes: ['/'], 5 }); 6 7 export const config = { 8 runtime: 'nodejs', 9 matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], 10 }; ``` * Python ```ts 1 app.get('/dashboard', auth.requiresAuth, (req, res) => { 2 res.json({ user: req.scalekitUser }); 3 }); ``` * Go middleware.ts ```ts 1 import { auth } from './lib/auth'; 2 3 export default auth.createMiddleware({ 4 publicRoutes: ['/'], 5 }); 6 7 export const config = { 8 runtime: 'nodejs', 9 matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], 10 }; ``` * Java * Flask ```py 1 @app.route("/dashboard") 2 @auth.requires_auth 3 def dashboard(): 4 return {"user": auth.current_user} ``` * FastAPI ```py 1 @app.get("/dashboard") 2 async def dashboard(user: dict = Depends(auth.requires_auth)): 3 return {"user": user} ``` * Express ```py 1 @app.route("/dashboard") 2 @auth.requires_auth 3 def dashboard(): 4 return {"user": auth.current_user} ``` * Next.js ```py 1 @app.get("/dashboard") 2 async def dashboard(user: dict = Depends(auth.requires_auth)): 3 return {"user": user} ``` * Flask ```go 1 import ( 2 "context" 3 "net/http" 4 ) 5 6 // verifyToken is a middleware that ensures a valid access token or refreshes it if expired. 7 func verifyToken(next http.HandlerFunc) http.HandlerFunc { 8 return func(w http.ResponseWriter, r *http.Request) { 9 // Retrieve the access token from the user's cookie 10 cookie, err := r.Cookie("accessToken") 11 if err != nil { 12 // No access token cookie found; reject the request 13 http.Error(w, `{"message": "No access token provided"}`, http.StatusUnauthorized) 14 return 15 } 16 17 accessToken := cookie.Value 18 19 // Decrypt the access token before validation 20 decryptedAccessToken, err := decrypt(accessToken) 21 if err != nil { 22 // Could not decrypt access token; treat as invalid 23 http.Error(w, `{"message": "Token decryption failed"}`, http.StatusUnauthorized) 24 return 25 } 26 27 // Validate the access token using the Scalekit SDK 28 isValid, err := scalekitClient.ValidateAccessToken(r.Context(), decryptedAccessToken) 29 if err != nil || !isValid { 30 // Access token is invalid or expired 31 32 // Attempt to retrieve the stored refresh token 33 refreshToken, err := getStoredRefreshToken(r) 34 if err != nil { 35 // No refresh token is available; cannot continue 36 http.Error(w, `{"message": "No refresh token available"}`, http.StatusUnauthorized) 37 return 38 } 39 40 // Use the refresh token to obtain a new access token from Scalekit 41 tokenResponse, err := scalekitClient.RefreshAccessToken(r.Context(), refreshToken) 42 if err != nil { 43 // Refresh attempt failed; likely an expired or invalid refresh token 44 http.Error(w, `{"message": "Token refresh failed"}`, http.StatusUnauthorized) 45 return 46 } 47 48 // Save the new refresh token so it can be reused for future requests 49 err = storeRefreshToken(tokenResponse.RefreshToken) 50 if err != nil { 51 // Could not store the new refresh token 52 http.Error(w, `{"message": "Failed to store refresh token"}`, http.StatusInternalServerError) 53 return 54 } 55 56 // Encrypt the new access token before setting it in the cookie 57 encryptedNewAccessToken, err := encrypt(tokenResponse.AccessToken) 58 if err != nil { 59 // Could not encrypt new access token 60 http.Error(w, `{"message": "Token encryption failed"}`, http.StatusInternalServerError) 61 return 62 } 63 64 // Issue a new accessToken cookie with updated credentials 65 newCookie := &http.Cookie{ 66 Name: "accessToken", 67 Value: encryptedNewAccessToken, 68 HttpOnly: true, 69 Secure: true, 70 Path: "/", 71 SameSite: http.SameSiteStrictMode, 72 } 73 http.SetCookie(w, newCookie) 74 75 // Mark the token as valid in the request context and proceed 76 r = r.WithContext(context.WithValue(r.Context(), "tokenValid", true)) 77 } else { 78 // The access token is valid; continue with marked context 79 r = r.WithContext(context.WithValue(r.Context(), "tokenValid", true)) 80 } 81 82 // Pass the request along to the next handler in the chain 83 next(w, r) 84 } 85 } 86 87 // dashboardHandler demonstrates a protected route that requires authentication. 88 func dashboardHandler(w http.ResponseWriter, r *http.Request) { 89 w.Header().Set("Content-Type", "application/json") 90 w.Write([]byte(`{ 91 "message": "This is a protected route", 92 "tokenValid": true 93 }`)) 94 } 95 96 // Usage example: 97 // Attach middleware to the /dashboard route: 98 // http.HandleFunc("/dashboard", verifyToken(dashboardHandler)) ``` * FastAPI ```java 1 import javax.servlet.http.HttpServletRequest; 2 import javax.servlet.http.HttpServletResponse; 3 import javax.servlet.http.Cookie; 4 import org.springframework.web.servlet.HandlerInterceptor; 5 6 @Component 7 public class TokenVerificationInterceptor implements HandlerInterceptor { 8 @Override 9 public boolean preHandle( 10 HttpServletRequest request, 11 HttpServletResponse response, 12 Object handler 13 ) throws Exception { 14 try { 15 // Get access token from cookie 16 String accessToken = getCookieValue(request, "accessToken"); 17 String refreshToken = getCookieValue(request, "refreshToken"); 18 19 // Decrypt the tokens 20 String decryptedAccessToken = decrypt(accessToken); 21 String decryptedRefreshToken = decrypt(refreshToken); 22 23 // Use Scalekit SDK to validate the token 24 boolean isValid = scalekit.authentication().validateAccessToken(decryptedAccessToken); 25 26 27 // Use refreshToken to get a new access token 28 AuthenticationResponse tokenResponse = scalekit 29 .authentication() 30 .refreshToken(decryptedRefreshToken); 31 32 // Update the cookie with the new access token and refresh token 33 String encryptedNewAccessToken = encrypt(tokenResponse.getAccessToken()); 34 String encryptedNewRefreshToken = encrypt(tokenResponse.getRefreshToken()); 35 36 Cookie accessTokenCookie = new Cookie("accessToken", encryptedNewAccessToken); 37 accessTokenCookie.setHttpOnly(true); 38 accessTokenCookie.setSecure(true); 39 accessTokenCookie.setPath("/"); 40 response.addCookie(accessTokenCookie); 41 42 Cookie refreshTokenCookie = new Cookie("refreshToken", encryptedNewRefreshToken); 43 refreshTokenCookie.setHttpOnly(true); 44 refreshTokenCookie.setSecure(true); 45 refreshTokenCookie.setPath("/"); 46 response.addCookie(refreshTokenCookie); 47 48 return true; 49 } catch (Exception e) { 50 // handle exception 51 } 52 } 53 54 private String getCookieValue(HttpServletRequest request, String cookieName) { 55 Cookie[] cookies = request.getCookies(); 56 if (cookies != null) { 57 for (Cookie cookie : cookies) { 58 if (cookieName.equals(cookie.getName())) { 59 return cookie.getValue(); 60 } 61 } 62 } 63 return null; 64 } 65 } ``` Authenticated users can access your dashboard. The app enforces session policies using session tokens. To change session policies, go to Dashboard > Authentication > Session Policy in the Scalekit dashboard. 5. ## Log out the user [Section titled “Log out the user”](#log-out-the-user) Session persistence depends on the session policy configured in the Scalekit dashboard. To log out a user, clear local session data and invalidate the user’s session in Scalekit. * Node.js * Express ```html 1 Log out ``` * Next.js app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` ```html 1 Log out ``` * Python ```html 1 Log out ``` * Go app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` ```html 1 Log out ``` * Java * Flask ```html 1 Log out ``` * FastAPI ```html 1 Log out ``` * Express ```html 1 Log out ``` * Next.js ```html 1 Log out ``` * Flask ```go 1 package main 2 3 import ( 4 "net/http" 5 "github.com/gin-gonic/gin" 6 "github.com/scalekit-inc/scalekit-sdk-go" 7 ) 8 9 func logoutHandler(c *gin.Context) { 10 // Clear all session data including cookies and local storage 11 clearSessionData() 12 13 // Generate Scalekit logout URL 14 options := scalekit.LogoutUrlOptions{ 15 IdTokenHint: idToken, 16 PostLogoutRedirectUri: postLogoutRedirectUri, 17 } 18 logoutUrl, err := scalekitClient.GetLogoutUrl(options) 19 if err != nil { 20 c.JSON(http.StatusInternalServerError, gin.H{ 21 "error": "Failed to generate logout URL", 22 }) 23 return 24 } 25 26 // Redirect to Scalekit's logout endpoint 27 // Note: This is a one-time use URL that becomes invalid after use 28 c.Redirect(http.StatusFound, logoutUrl.String()) 29 } ``` * FastAPI ```java 1 import com.scalekit.internal.http.LogoutUrlOptions; 2 import org.springframework.web.bind.annotation.*; 3 import org.springframework.web.servlet.view.RedirectView; 4 import java.net.URL; 5 6 @RestController 7 public class LogoutController { 8 9 @GetMapping("/logout") 10 public RedirectView logout() { 11 12 clearSessionData(); 13 14 15 LogoutUrlOptions options = new LogoutUrlOptions(); 16 options.setIdTokenHint(idToken); 17 options.setPostLogoutRedirectUri(postLogoutRedirectUri); 18 19 URL logoutUrl = scalekit.authentication() 20 .getLogoutUrl(options); 21 22 23 // Note: This is a one-time use URL that becomes invalid after use 24 return new RedirectView(logoutUrl.toString()); 25 } 26 } ``` The logout process completes when Scalekit invalidates the user’s session and redirects them to your [registered post-logout URL](/guides/dashboard/redirects/#post-logout-url). This single integration unlocks multiple authentication methods, including Magic Link & OTP, social sign-ins, enterprise single sign-on (SSO), and robust user management features. As you continue working with Scalekit, you’ll discover even more features that enhance your authentication workflows. --- # DOCUMENT BOUNDARY --- # Add OAuth 2.1 authorization to MCP servers > Secure your Model Context Protocol (MCP) servers with Scalekit's drop-in OAuth 2.1 authorization solution and protect your AI integrations This guide shows you how to add production-ready OAuth 2.1 authorization to your Model Context Protocol (MCP) server using Scalekit. You’ll learn how to secure your MCP server so that only authenticated and authorized users can access your tools through AI hosts like Claude Desktop, Cursor, or VS Code. Using a coding agent?Copy MCP prompt MCP servers expose tools that AI hosts can discover and execute to interact with your resources. For example: * A sales team member could use Claude Desktop to view customer information, update records, or set follow-up reminders * A developer could use VS Code or Cursor with a GitHub MCP server to perform everyday GitHub actions through chat * An autonomous agent could use an MCP server to perform actions such as look up the account details in a CRM system When you build MCP servers, multiple AI hosts may need to discover and use your server to interact with your resources. Scalekit handles the complex authentication and authorization for you, so you can focus on building better tools and improving functionality. 1. ## Get Scalekit SDK [Section titled “Get Scalekit SDK”](#get-scalekit-sdk) To get started, make sure you have your Scalekit account and API credentials ready. If you haven’t created a Scalekit account yet, you can [sign up and get a free account](https://app.scalekit.com/ws/signup). Next, install the Scalekit SDK for your language: * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` Use the Scalekit dashboard to register your MCP server and configure MCP hosts (or AI agents following the MCP client protocol) to use Scalekit as the authorization server. The Scalekit SDK validates tokens after users have been authenticated and authorized to access your MCP server. 2. ## Add MCP server to get drop-in OAuth2.1 authorization server [Section titled “Add MCP server to get drop-in OAuth2.1 authorization server”](#add-mcp-server-to-get-drop-in-oauth21-authorization-server) In the Scalekit dashboard, go to **MCP servers** and select **Add MCP server**. ![Add MCP server](/.netlify/images?url=_astro%2Fmcp-create.wpqhshLD.png\&w=1068\&h=864\&dpl=6aaa70ad2ea7b40008ad2afd) 1. Provide a **name** for your MCP server to help you identify it easily. This name appears on the Consent page that MCP hosts display to users when authorizing access to your MCP server. 2. Enable **dynamic client registration** for MCP hosts. This allows MCP hosts to automatically register with Scalekit (and your authorization server), eliminating the need for manual registration and making it easier for users to adopt your MCP server secur. 3. Enable **Client ID Metadata Document (CIMD)** to allow your authorization server to fetch client metadata from MCP hosts and authorize them automatically. 4. Click **Save** to register the server. Note: If your MCP server is intended for use by public MCP clients such as Claude, Cursor, or VS Code, it is recommended to keep both DCR and CIMD enabled. Clients that support CIMD will use the CIMD flow, while clients that do not yet support CIMD can fall back to Dynamic Client Registration. This ensures your MCP server remains compatible with the widest range of MCP clients while preserving a smooth authorization experience. Toggling DCR or CIMD? If you enable or disable DCR or CIMD, be sure to restart your MCP server. Certain MCP frameworks, like FastMCP, cache authorization server details, and a restart ensures the updated configuration is correctly applied. 3. ## Let MCP clients discover your OAuth2.1 authorization server [Section titled “Let MCP clients discover your OAuth2.1 authorization server”](#let-mcp-clients-discover-your-oauth21-authorization-server) MCP protocol directs any MCP client to discover your OAuth2.1 authorization server by calling a public endpoint on your MCP server. This endpoint is called `.well-known/oauth-protected-resource` and your MCP server must host this endpoint. ![MCP server setup](/.netlify/images?url=_astro%2Fmcp-metadata.BIWBrsCY.png\&w=1126\&h=1326\&dpl=6aaa70ad2ea7b40008ad2afd) Copy the resource metadata JSON from **Dashboard > MCP Servers > Your server > Metadata JSON** and implement it in your `.well-known/oauth-protected-resource` endpoint. The `authorization_servers` field contains your Scalekit resource identifier, which clients use to initiate the OAuth flow. * Node.js ```javascript // MCP client discovery endpoint // Use case: Allow MCP clients to discover OAuth authorization server configuration app.get('/.well-known/oauth-protected-resource', (req, res) => { res.json({ // From Scalekit dashboard > MCP servers > Your server > Metadata JSON "authorization_servers": [ "https:///resources/" ], "bearer_methods_supported": [ "header" // Bearer token in Authorization header ], "resource": "https://mcp.yourapp.com", // Your MCP server URL "resource_documentation": "https://mcp.yourapp.com/docs", // A URL to the documentation of the resource server "scopes_supported": ["todo:read", "todo:write"] // Dashboard-configured scopes }); }); ``` * Python ```python from fastapi import FastAPI from fastapi.responses import JSONResponse app = FastAPI() # OAuth Protected Resource Metadata endpoint - Required for MCP client discovery # Copy the actual authorization server URL and metadata from your Scalekit dashboard. # The values shown here are examples - replace with your actual configuration. @app.get("/.well-known/oauth-protected-resource") async def get_oauth_protected_resource(): return JSONResponse({ "authorization_servers": [ "https:///resources/" ], "bearer_methods_supported": [ "header" ], "resource": "https://mcp.yourapp.com", "resource_documentation": "https://mcp.yourapp.com/docs", "scopes_supported": ["todo:read", "todo:write"] }) ``` 4. ## Validate all MCP client requests have a valid access token [Section titled “Validate all MCP client requests have a valid access token”](#validate-all-mcp-client-requests-have-a-valid-access-token) Your MCP server should validate that all incoming requests contain a valid access token. Leverage Scalekit SDKs to validate tokens and verify essential claims such as `aud` (audience), `iss` (issuer), `exp` (expiration), `iat` (issued at), and `scope` (permissions). * Node.js auth-config.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 // Initialize Scalekit client with environment credentials 4 // Reference installation guide for client setup details 5 const scalekit = new Scalekit( 6 process.env.SCALEKIT_ENVIRONMENT_URL, 7 process.env.SCALEKIT_CLIENT_ID, 8 process.env.SCALEKIT_CLIENT_SECRET 9 ); 10 11 // Resource configuration 12 // Get these values from Scalekit dashboard > MCP servers > Your server 13 // For FastMCP: Use base URL with trailing slash (e.g., https://mcp.example.com/) 14 const RESOURCE_ID = 'https://your-mcp-server.com'; // If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard. 15 const METADATA_ENDPOINT = 'https://your-mcp-server.com/.well-known/oauth-protected-resource'; 16 17 // WWW-Authenticate header for unauthorized responses 18 // This helps clients understand how to authenticate properly 19 export const WWWHeader = { 20 HeaderKey: 'WWW-Authenticate', 21 HeaderValue: `Bearer realm="OAuth", resource_metadata="${METADATA_ENDPOINT}"` 22 }; ``` * Python auth\_config.py ```python 1 from scalekit import ScalekitClient 2 from scalekit.common.scalekit import TokenValidationOptions 3 import os 4 5 # Initialize Scalekit client with environment credentials 6 # Reference installation guide for client setup details 7 scalekit_client = ScalekitClient( 8 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 9 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 10 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 11 ) 12 13 # Resource configuration 14 # Get these values from Scalekit dashboard > MCP servers > Your server 15 # For FastMCP: Use base URL with trailing slash (e.g., https://mcp.example.com/) 16 RESOURCE_ID = "https://your-mcp-server.com" # If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard. 17 METADATA_ENDPOINT = "https://your-mcp-server.com/.well-known/oauth-protected-resource" 18 19 # WWW-Authenticate header for unauthorized responses 20 # This helps clients understand how to authenticate properly 21 WWW_HEADER = { 22 "WWW-Authenticate": f'Bearer realm="OAuth", resource_metadata="{METADATA_ENDPOINT}"' 23 } ``` Extract the Bearer token from incoming MCP client requests. MCP clients send tokens in the `Authorization: Bearer ` header format. * Node.js ```javascript 1 // Extract Bearer token from Authorization header 2 // Use case: Validate requests from AI hosts like Claude Desktop, Cursor, or VS Code 3 const authHeader = req.headers['authorization']; 4 const token = authHeader?.startsWith('Bearer ') 5 ? authHeader.split('Bearer ')[1]?.trim() 6 : null; 7 8 if (!token) { 9 throw new Error('Missing or invalid Bearer token'); 10 } ``` * Python ```python 1 # Extract Bearer token from Authorization header 2 # Use case: Validate requests from AI hosts like Claude Desktop, Cursor, or VS Code 3 auth_header = request.headers.get("Authorization", "") 4 token = None 5 if auth_header.startswith("Bearer "): 6 token = auth_header.split("Bearer ")[1].strip() 7 8 if not token: 9 raise ValueError("Missing or invalid Bearer token") ``` Validate the token against your configured resource audience to ensure it was issued for your specific MCP server. The resource identifier must match the Server URL you registered earlier. * Node.js Validate token ```javascript 1 // Security: Validate token against configured resource audience 2 // This ensures the token was issued for your specific MCP server 3 await scalekit.validateToken(token, { 4 issuer: '' 5 audience: [RESOURCE_ID] 6 }); ``` * Python Validate token ```python 1 # Method 1: validate_access_token - Returns boolean (True/False) 2 # Use this method when you only need to verify token validity without detailed error information. 3 # This approach is suitable for simple authorization checks where you don't need token claims. 4 def validate_token_with_issuer_audience(token: str) -> bool: 5 """ 6 Validates a token and returns True if valid, False otherwise. 7 8 :param token: The token to validate 9 :return: True if token is valid, False otherwise 10 """ 11 options = TokenValidationOptions( 12 issuer="", 13 audience=[RESOURCE_ID] 14 ) 15 16 try: 17 is_valid = scalekit_client.validate_access_token(token, options=options) 18 return is_valid 19 except Exception as ex: 20 print(f"Token validation failed: {ex}") 21 return False 22 23 # Method 2: validate_token - Returns token claims/payload 24 # Use this method when you need access to token claims (user info, scopes, etc.) or detailed error information. 25 # This approach is suitable for authorization that requires specific user context or scope validation. 26 def validate_token_and_get_claims(token: str) -> dict: 27 """ 28 Validates a token with specific audience and raises exception on failure. 29 30 :param token: The token to validate 31 :raises: ScalekitValidateTokenFailureException if validation fails 32 """ 33 options = TokenValidationOptions( 34 issuer="", 35 audience=[RESOURCE_ID], 36 required_scopes=["todo:read", "todo:write"] # Optional: validate specific scopes for finer access control 37 ) 38 39 scalekit_client.validate_token(token, options=options) ``` * Go middleware/auth.go ```go 1 // Security: validate the token's issuer and audience — confirms it was issued by 2 // your Scalekit environment for your specific MCP server. 3 ok, err := scalekitClient.ValidateTokenWithOptions(ctx, token, &scalekit.ValidateTokenOptions{ 4 Issuer: "", 5 Audience: []string{RESOURCE_ID}, 6 }) 7 if err != nil || !ok { 8 // Reject: return 401 with the WWW-Authenticate header and stop processing. 9 w.Header().Set("WWW-Authenticate", wwwAuthenticateHeader) 10 http.Error(w, "invalid token", http.StatusUnauthorized) 11 return 12 } 13 // Token is valid — continue handling the request. 14 15 // Prefer validating scopes per tool-call rather than in this global check, so each 16 // tool enforces only the scope it needs. ``` * Java middleware/AuthMiddleware.java ```java 1 // Security: validate the token's issuer and audience — confirms it was issued by 2 // your Scalekit environment for your specific MCP server. 3 boolean isValid = scalekitClient.authentication().validateAccessToken( 4 token, 5 TokenValidationOptions.builder() 6 .issuer("") 7 .audience(List.of(RESOURCE_ID)) 8 .build() 9 ); 10 if (!isValid) { 11 // Reject: return 401 with the WWW-Authenticate header and stop processing. 12 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 13 response.setHeader("WWW-Authenticate", wwwAuthenticateHeader); 14 return; 15 } 16 // Token is valid — continue handling the request. 17 18 // Prefer enforcing scopes per tool-call rather than in this global check: read the 19 // token's "scope" claim via validateAccessTokenAndGetClaims(token, options) inside 20 // each tool and verify it contains the scope that tool needs. ``` #### Complete middleware implementation [Section titled “Complete middleware implementation”](#complete-middleware-implementation) Combine token extraction and validation into a complete authentication middleware that protects all your MCP endpoints. * Node.js ```javascript import { Scalekit } from '@scalekit-sdk/node'; import { NextFunction, Request, Response } from 'express'; const scalekit = new Scalekit( process.env.SCALEKIT_ENVIRONMENT_URL, process.env.SCALEKIT_CLIENT_ID, process.env.SCALEKIT_CLIENT_SECRET ); const RESOURCE_ID = 'https://your-mcp-server.com'; // If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard. const METADATA_ENDPOINT = 'https://your-mcp-server.com/.well-known/oauth-protected-resource'; export const WWWHeader = { HeaderKey: 'WWW-Authenticate', HeaderValue: `Bearer realm="OAuth", resource_metadata="${METADATA_ENDPOINT}"` }; export async function authMiddleware(req: Request, res: Response, next: NextFunction) { try { // Security: Allow public access to well-known endpoints for metadata discovery // This enables MCP clients to discover your OAuth configuration if (req.path.includes('.well-known')) { return next(); } // Extract Bearer token from Authorization header const authHeader = req.headers['authorization']; const token = authHeader?.startsWith('Bearer ') ? authHeader.split('Bearer ')[1]?.trim() : null; if (!token) { throw new Error('Missing or invalid Bearer token'); } // Security: Validate token against configured resource audience await scalekit.validateToken(token, { audience: [RESOURCE_ID] }); next(); } catch (err) { // Return proper OAuth 2.0 error response with WWW-Authenticate header return res .status(401) .set(WWWHeader.HeaderKey, WWWHeader.HeaderValue) .end(); } } // Apply authentication middleware to all MCP endpoints app.use('/', authMiddleware); ``` * Python ```python from scalekit import ScalekitClient from scalekit.common.scalekit import TokenValidationOptions from fastapi import Request, HTTPException, status from fastapi.responses import Response import os scalekit_client = ScalekitClient( env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") ) RESOURCE_ID = "https://your-mcp-server.com" # If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard. METADATA_ENDPOINT = "https://your-mcp-server.com/.well-known/oauth-protected-resource" # WWW-Authenticate header for unauthorized responses WWW_HEADER = { "WWW-Authenticate": f'Bearer realm="OAuth", resource_metadata="{METADATA_ENDPOINT}"' } async def auth_middleware(request: Request, call_next): # Security: Allow public access to well-known endpoints for metadata discovery if request.url.path.startswith("/.well-known"): return await call_next(request) # Extract Bearer token from Authorization header auth_header = request.headers.get("Authorization", "") token = None if auth_header.startswith("Bearer "): token = auth_header.split("Bearer ")[1].strip() if not token: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, headers=WWW_HEADER ) # Security: Validate token against configured resource audience try: options = TokenValidationOptions( issuer=os.getenv("SCALEKIT_ENVIRONMENT_URL"), audience=[RESOURCE_ID] ) scalekit_client.validate_token(token, options=options) except Exception: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, headers=WWW_HEADER ) return await call_next(request) # Apply authentication middleware to all MCP endpoints app.middleware("http")(auth_middleware) ``` 5. ## Implement scope-based tool authorization Optional [Section titled “Implement scope-based tool authorization ”](#implement-scope-based-tool-authorization-) Add scope validation at the MCP tool execution level to ensure tools are only executed when the user has authorized the MCP client with the required permissions. This provides fine-grained access control and follows the principle of least privilege. * Node.js ```diff 1 // Security: Validate token has required scope for this specific tool execution 2 // Use case: Ensure users only have access to authorized MCP tools 3 try { 4 await scalekit.validateToken( 5 token, { 6 audience: [RESOURCE_ID], 7 requiredScopes: [scope] 8 } 9 ); 10 } catch(error) { 11 // Return OAuth 2.0 compliant error for insufficient scope 12 return res.status(403).json({ 13 error: 'insufficient_scope', 14 error_description: `Required scope: ${scope}`, 15 scope: scope 16 }); 17 } ``` * Python ```diff 1 # Security: Validate token has required scope for this specific tool execution 2 # Use case: Ensure users only have access to authorized MCP tools 3 try: 4 scalekit_client.validate_access_token( 5 token, 6 options=TokenValidationOptions( 7 audience=[RESOURCE_ID], 8 +required_scopes=[scope] 9 ) 10 ) 11 except ScalekitValidateTokenFailureException as ex: 12 # Return OAuth 2.0 compliant error for insufficient scope 13 return { 14 "error": "insufficient_scope", 15 "error_description": f"Required scope: {scope}", 16 "scope": scope 17 } ``` 6. ## Enable additional authentication methods [Section titled “Enable additional authentication methods”](#enable-additional-authentication-methods) Beyond the OAuth 2.1 authorization you’ve implemented, you can enable additional authentication methods that work seamlessly with your MCP server’s token validation: **[Enterprise SSO](/mcp/auth-methods/enterprise/)** Enable organizations to authenticate through their identity providers (Okta, Azure AD, Google Workspace). Your MCP server continues validating tokens the same way, while Scalekit handles: * Centralized access control through existing enterprise identity systems * Single sign-on experience for organization members * Compliance with corporate security policies **[Social logins](/mcp/auth-methods/social/)** Allow users to authenticate via Google, GitHub, Microsoft, and other social providers. Your existing token validation logic remains unchanged while providing: * Quick onboarding for individual users * Familiar authentication experience * Reduced friction for personal and small team use cases These authentication methods require no changes to your MCP server implementation—you continue validating tokens exactly as shown in the previous steps. **[Bring your own auth](/mcp/auth-methods/custom-auth/)** allows you to use your own authentication system to authenticate users to your MCP server. Your MCP server now has production-ready OAuth 2.1 authorization! You’ve successfully implemented a secure authorization flow that protects your MCP tools and ensures only authenticated users can access them through AI hosts. **Try the demo**: Download and run our [sample MCP server](https://github.com/scalekit-inc/mcp-auth-demos) with authentication already configured to see the complete integration in action. In summary, **Scalekit OAuth authorization server** Acts as the identity provider for your MCP server. * Authenticates users and agents * Issues access tokens with fine-grained scopes * Manages OAuth 2.1 flows (authorization code, client credentials) * Supports dynamic client registration for easy onboarding **Your MCP server** Validates incoming access tokens and enforces the permissions encoded in each token. Only requests with valid, authorized tokens are allowed. This separation of responsibilities ensures a clear boundary: Scalekit handles identity and token issuance, while your MCP server focuses on business logic of executing the actual tool calls. --- # DOCUMENT BOUNDARY --- # Add Modular SCIM provisioning > Automate user provisioning with SCIM. Directory API and webhooks for real-time user data sync This guide shows you how to automate user provisioning with SCIM using Scalekit’s Directory API and webhooks. You’ll learn to sync user data in real-time, create webhook endpoints for instant updates, and build automated provisioning workflows that keep your application’s user data synchronized with your customers’ directory providers. With [SCIM Provisioning](/directory/guides/user-provisioning-basics) from Scalekit, you can: * Use **webhooks** to listen for events from your customers’ directory providers (e.g., user updates, group changes) * Use **REST APIs** to list users, groups, and directories on demand Scalekit abstracts the complexities of various directory providers, giving you a single interface to automate user lifecycle management. This enables you to create accounts for new hires during onboarding, deactivate accounts when employees depart, and adjust access levels as employees change roles. ![SCIM Quickstart](/.netlify/images?url=_astro%2Fscim-chart.D8FO-9f1.png\&w=5776\&h=1924\&dpl=6aaa70ad2ea7b40008ad2afd) Using a coding agent?Copy SCIM prompt ## User provisioning with Scalekit’s directory API [Section titled “User provisioning with Scalekit’s directory API”](#user-provisioning-with-scalekits-directory-api) Scalekit’s directory API allows you to fetch information about users, groups, and directories associated with an organization on-demand. This approach is ideal for scheduled synchronization tasks, bulk data imports, or when you need to ensure your application’s user data matches the latest directory provider state. Let’s explore how to use the Directory API to retrieve user and group data programmatically. 1. ### Setting up the SDK [Section titled “Setting up the SDK”](#setting-up-the-sdk) Before you begin, ensure that your organization [has a directory set up in Scalekit](/guides/user-management/scim-provisioning/). Scalekit offers language-specific SDKs for fast SSO integration. Use the installation instructions below for your technology stack: * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Navigate to **Dashboard > Developers > Settings > API Credentials** to obtain your credentials. Store your credentials securely in environment variables: .env ```shell 1 # Get these values from Dashboard > Developers > Settings > API Credentials 2 SCALEKIT_ENVIRONMENT_URL='https://b2b-app-dev.scalekit.com' 3 SCALEKIT_CLIENT_ID='' 4 SCALEKIT_CLIENT_SECRET='' ``` 2. ### Initialize the SDK and make your first API call [Section titled “Initialize the SDK and make your first API call”](#initialize-the-sdk-and-make-your-first-api-call) Initialize the Scalekit client with your environment variables and make your first API call to list organizations. * cURL Terminal ```bash 1 # Security: Replace with a valid access token from Scalekit 2 # This token authorizes your API requests to access organization data 3 4 # Use case: Verify API connectivity and test authentication 5 # Examples: Initial setup testing, debugging integration issues 6 7 curl -L "https://$SCALEKIT_ENVIRONMENT_URL/api/v1/organizations?page_size=5" \ 8 -H "Authorization: Bearer " ``` * Node.js Node.js ```javascript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 3 // Initialize Scalekit client with environment variables 4 // Security: Always use environment variables for sensitive credentials 5 const scalekit = new ScalekitClient( 6 process.env.SCALEKIT_ENVIRONMENT_URL, 7 process.env.SCALEKIT_CLIENT_ID, 8 process.env.SCALEKIT_CLIENT_SECRET, 9 ); 10 11 try { 12 // Use case: Retrieve organizations for bulk user provisioning workflows 13 // Examples: Multi-tenant applications, enterprise customer onboarding 14 const { organizations } = await scalekit.organization.listOrganization({ 15 pageSize: 5, 16 }); 17 18 console.log(`Organization name: ${organizations[0].display_name}`); 19 console.log(`Organization ID: ${organizations[0].id}`); 20 } catch (error) { 21 console.error('Failed to list organizations:', error); 22 // Handle error appropriately for your application 23 } ``` * Python Python ```python 1 from scalekit import ScalekitClient 2 import os 3 4 # Initialize the SDK client with environment variables 5 # Security: Use os.getenv() to securely access credentials 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 10 ) 11 12 try: 13 # Use case: Sync user data across multiple organizations 14 # Examples: Scheduled provisioning tasks, HR system integration 15 org_list = scalekit_client.organization.list_organizations(page_size=100) 16 17 if org_list: 18 print(f'Organization details: {org_list[0]}') 19 print(f'Organization ID: {org_list[0].id}') 20 except Exception as error: 21 print(f'Error listing organizations: {error}') 22 # Implement appropriate error handling for your use case ``` * Go Go ```go 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 "github.com/scalekit/scalekit-go" 9 ) 10 11 // Initialize Scalekit client with environment variables 12 // Security: Always load credentials from environment, not hardcoded 13 scalekitClient := scalekit.NewScalekitClient( 14 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 15 os.Getenv("SCALEKIT_CLIENT_ID"), 16 os.Getenv("SCALEKIT_CLIENT_SECRET"), 17 ) 18 19 // Use case: Get specific organization for directory sync operations 20 // Examples: Targeted user provisioning, organization-specific workflows 21 organization, err := scalekitClient.Organization.GetOrganization( 22 ctx, 23 organizationId, 24 ) 25 if err != nil { 26 // Handle error appropriately for your application 27 return fmt.Errorf("failed to get organization: %w", err) 28 } ``` * Java Java ```java 1 import com.scalekit.ScalekitClient; 2 3 // Initialize Scalekit client with environment variables 4 // Security: Use System.getenv() to securely access credentials 5 ScalekitClient scalekitClient = new ScalekitClient( 6 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 7 System.getenv("SCALEKIT_CLIENT_ID"), 8 System.getenv("SCALEKIT_CLIENT_SECRET") 9 ); 10 11 try { 12 // Use case: List organizations for automated provisioning workflows 13 // Examples: Enterprise customer setup, multi-tenant management 14 ListOrganizationsResponse organizations = scalekitClient.organizations() 15 .listOrganizations(5, ""); 16 17 if (!organizations.getOrganizations().isEmpty()) { 18 Organization firstOrg = organizations.getOrganizations().get(0); 19 System.out.println("Organization name: " + firstOrg.getDisplayName()); 20 System.out.println("Organization ID: " + firstOrg.getId()); 21 } 22 } catch (ScalekitException error) { 23 System.err.println("Failed to list organizations: " + error.getMessage()); 24 // Implement appropriate error handling 25 } ``` 3. ### Retrieve a directory [Section titled “Retrieve a directory”](#retrieve-a-directory) After successfully listing organizations, you’ll need to retrieve the specific directory to begin syncing user and group data. You can retrieve directories using either the organization and directory IDs, or fetch the primary directory for an organization. * Node.js Node.js ```javascript 1 try { 2 // Use case: Get specific directory when organization has multiple directories 3 // Examples: Department-specific provisioning, multi-division companies 4 const { directory } = await scalekit.directory.getDirectory('', ''); 5 console.log(`Directory name: ${directory.name}`); 6 7 // Use case: Get primary directory for simple provisioning workflows 8 // Examples: Small organizations, single-directory setups 9 const { directory } = await scalekit.directory.getPrimaryDirectoryByOrganizationId(''); 10 console.log(`Primary directory ID: ${directory.id}`); 11 } catch (error) { 12 console.error('Failed to retrieve directory:', error); 13 // Handle error appropriately for your application 14 } ``` * Python Python ```python 1 try: 2 # Use case: Access specific directory for targeted user sync operations 3 # Examples: Regional offices, business unit-specific provisioning 4 directory = scalekit_client.directory.get_directory( 5 organization_id='', directory_id='' 6 ) 7 print(f'Directory name: {directory.name}') 8 9 # Use case: Get primary directory for streamlined user management 10 # Examples: Standard employee provisioning, main company directory 11 primary_directory = scalekit_client.directory.get_primary_directory_by_organization_id( 12 organization_id='' 13 ) 14 print(f'Primary directory ID: {primary_directory.id}') 15 except Exception as error: 16 print(f'Error retrieving directory: {error}') 17 # Implement appropriate error handling ``` * Go Go ```go 1 // Use case: Retrieve specific directory for granular access control 2 // Examples: Multi-tenant environments, department-level provisioning 3 directory, err := scalekitClient.Directory().GetDirectory(ctx, organizationId, directoryId) 4 if err != nil { 5 return fmt.Errorf("failed to get directory: %w", err) 6 } 7 fmt.Printf("Directory name: %s\n", directory.Name) 8 9 // Use case: Get primary directory for simplified user management 10 // Examples: Automated provisioning workflows, bulk user imports 11 directory, err := scalekitClient.Directory().GetPrimaryDirectoryByOrganizationId(ctx, organizationId) 12 if err != nil { 13 return fmt.Errorf("failed to get primary directory: %w", err) 14 } 15 fmt.Printf("Primary directory ID: %s\n", directory.ID) ``` * Java Java ```java 1 try { 2 // Use case: Access specific directory for detailed user management 3 // Examples: Custom provisioning logic, directory-specific rules 4 Directory directory = scalekitClient.directories() 5 .getDirectory("", ""); 6 System.out.println("Directory name: " + directory.getName()); 7 8 // Use case: Get primary directory for standard provisioning workflows 9 // Examples: Employee onboarding, automated user sync 10 Directory primaryDirectory = scalekitClient.directories() 11 .getPrimaryDirectoryByOrganizationId(""); 12 System.out.println("Primary directory ID: " + primaryDirectory.getId()); 13 } catch (ScalekitException error) { 14 System.err.println("Failed to retrieve directory: " + error.getMessage()); 15 // Implement appropriate error handling 16 } ``` 4. ### List users in a directory [Section titled “List users in a directory”](#list-users-in-a-directory) Once you have the directory information, you can fetch users within that directory. This is commonly used for bulk user synchronization and maintaining an up-to-date user database. * Node.js Node.js ```javascript 1 try { 2 // Use case: Bulk user synchronization and provisioning 3 // Examples: New customer onboarding, scheduled user data sync 4 const { users } = await scalekit.directory.listDirectoryUsers('', ''); 5 6 // Process each user for provisioning or updates 7 users.forEach(user => { 8 console.log(`User email: ${user.email}, Name: ${user.name}`); 9 // TODO: Implement your user provisioning logic here 10 }); 11 } catch (error) { 12 console.error('Failed to list directory users:', error); 13 // Handle error appropriately for your application 14 } ``` * Python Python ```python 1 try: 2 # Use case: Automated user provisioning workflows 3 # Examples: HR system integration, bulk user imports 4 directory_users = scalekit_client.directory.list_directory_users( 5 organization_id='', directory_id='' 6 ) 7 8 # Process each user for local database updates 9 for user in directory_users: 10 print(f'User email: {user.email}, Name: {user.name}') 11 # TODO: Implement your user synchronization logic here 12 except Exception as error: 13 print(f'Error listing directory users: {error}') 14 # Implement appropriate error handling ``` * Go Go ```go 1 // Configure pagination options for large user directories 2 options := &ListDirectoryUsersOptions{ 3 PageSize: 50, // Adjust based on your needs 4 PageToken: "", 5 } 6 7 // Use case: Paginated user retrieval for large directories 8 // Examples: Enterprise customer provisioning, regular sync jobs 9 directoryUsers, err := scalekitClient.Directory().ListDirectoryUsers(ctx, organizationId, directoryId, options) 10 if err != nil { 11 return fmt.Errorf("failed to list directory users: %w", err) 12 } 13 14 // Process each user 15 for _, user := range directoryUsers.Users { 16 fmt.Printf("User email: %s, Name: %s\n", user.Email, user.Name) 17 // TODO: Implement your user provisioning logic 18 } ``` * Java Java ```java 1 // Configure options for user listing with pagination 2 var options = ListDirectoryResourceOptions.builder() 3 .pageSize(50) // Adjust based on your requirements 4 .pageToken("") 5 .includeDetail(true) // Include detailed user information 6 .build(); 7 8 try { 9 // Use case: Enterprise user management and synchronization 10 // Examples: Scheduled sync tasks, user provisioning automation 11 ListDirectoryUsersResponse usersResponse = scalekitClient.directories() 12 .listDirectoryUsers(directory.getId(), organizationId, options); 13 14 // Process each user for provisioning 15 for (User user : usersResponse.getUsers()) { 16 System.out.println("User email: " + user.getEmail() + ", Name: " + user.getName()); 17 // TODO: Implement your user provisioning logic here 18 } 19 } catch (ScalekitException error) { 20 System.err.println("Failed to list directory users: " + error.getMessage()); 21 // Implement appropriate error handling 22 } ``` 5. ### List groups in a directory [Section titled “List groups in a directory”](#list-groups-in-a-directory) Groups are essential for implementing role-based access control (RBAC) in your application. After retrieving users, you can fetch groups to manage permissions and access levels based on organizational structure. * Node.js Node.js ```javascript 1 try { 2 // Use case: Role-based access control implementation 3 // Examples: Department-level permissions, project-based access 4 const { groups } = await scalekit.directory.listDirectoryGroups( 5 '', 6 '', 7 ); 8 9 // Process each group for RBAC setup 10 groups.forEach(group => { 11 console.log(`Group name: ${group.name}, ID: ${group.id}`); 12 // TODO: Implement your group-based permission logic here 13 }); 14 } catch (error) { 15 console.error('Failed to list directory groups:', error); 16 // Handle error appropriately for your application 17 } ``` * Python Python ```python 1 try: 2 # Use case: Department-based access control 3 # Examples: Engineering vs Sales permissions, project team access 4 directory_groups = scalekit_client.directory.list_directory_groups( 5 directory_id='', organization_id='' 6 ) 7 8 # Process each group for permission mapping 9 for group in directory_groups: 10 print(f'Group name: {group.name}, ID: {group.id}') 11 # TODO: Implement your group-based permission logic here 12 except Exception as error: 13 print(f'Error listing directory groups: {error}') 14 # Implement appropriate error handling ``` * Go Go ```go 1 // Configure pagination for group listing 2 options := &ListDirectoryGroupsOptions{ 3 PageSize: 25, // Adjust based on expected group count 4 PageToken: "", 5 } 6 7 // Use case: Organizational role management 8 // Examples: Enterprise role hierarchy, department-based access 9 directoryGroups, err := scalekitClient.Directory().ListDirectoryGroups(ctx, organizationId, directoryId, options) 10 if err != nil { 11 return fmt.Errorf("failed to list directory groups: %w", err) 12 } 13 14 // Process each group for RBAC implementation 15 for _, group := range directoryGroups.Groups { 16 fmt.Printf("Group name: %s, ID: %s\n", group.Name, group.ID) 17 // TODO: Implement your group-based permission logic 18 } ``` * Java Java ```java 1 // Configure options for detailed group information 2 var options = ListDirectoryResourceOptions.builder() 3 .pageSize(25) // Adjust based on your requirements 4 .pageToken("") 5 .includeDetail(true) // Include group membership details 6 .build(); 7 8 try { 9 // Use case: Enterprise permission management 10 // Examples: Role assignments, access level configurations 11 ListDirectoryGroupsResponse groupsResponse = scalekitClient.directories() 12 .listDirectoryGroups(directory.getId(), organizationId, options); 13 14 // Process each group for permission mapping 15 for (Group group : groupsResponse.getGroups()) { 16 System.out.println("Group name: " + group.getName() + ", ID: " + group.getId()); 17 // TODO: Implement your group-based permission logic here 18 } 19 } catch (ScalekitException error) { 20 System.err.println("Failed to list directory groups: " + error.getMessage()); 21 // Implement appropriate error handling 22 } ``` Scalekit’s Directory API provides a simple way to fetch user and group information on-demand. Refer to our [API reference](https://docs.scalekit.com/apis/) to explore more capabilities. ## Realtime user provisioning with webhooks [Section titled “Realtime user provisioning with webhooks”](#realtime-user-provisioning-with-webhooks) While the Directory API is perfect for scheduled synchronization, webhooks enable immediate, real-time user provisioning. When directory providers send events to Scalekit, we forward them instantly to your application, allowing you to respond to user changes as they happen. This approach is ideal for scenarios requiring immediate action, such as new employee onboarding or emergency access revocation. 1. ### Create a secure webhook endpoint [Section titled “Create a secure webhook endpoint”](#create-a-secure-webhook-endpoint) Create a webhook endpoint to receive real-time events from directory providers. After implementing your endpoint, register it in **Dashboard > Webhooks** where you’ll receive a secret for payload verification. Critical security requirement Always verify webhook signatures before processing events. This prevents unauthorized parties from triggering your provisioning logic and protects against replay attacks. * Node.js Express.js ```javascript 1 app.post( 2 '/webhook', 3 express.raw({ type: 'application/json' }), 4 async (req, res) => { 5 const secret = process.env.SCALEKIT_WEBHOOK_SECRET 6 const payload = req.body.toString() 7 const headers = { 8 'webhook-id': req.headers['webhook-id'], 9 'webhook-timestamp': req.headers['webhook-timestamp'], 10 'webhook-signature': req.headers['webhook-signature'], 11 } 12 13 try { 14 scalekit.verifyWebhookPayload(secret, headers, payload) 15 } catch (error) { 16 console.error('Webhook signature verification failed:', error) 17 return res.status(401).json({ error: 'Invalid signature' }) 18 } 19 20 const event = JSON.parse(payload) 21 22 try { 23 const { email, name } = event.data 24 25 // Process the webhook event based on its type 26 switch (event.type) { 27 case 'organization.directory.user_created': 28 await createUserAccount(email, name); 29 break; 30 case 'organization.directory.user_updated': 31 await updateUserAccount(email, name); 32 break; 33 case 'organization.directory.user_deleted': 34 await deactivateUserAccount(email); 35 break; 36 default: 37 console.log(`Unhandled event type: ${event.type}`); 38 } 39 40 res.status(201).json({ message: 'Webhook processed successfully' }); 41 } catch (processingError) { 42 console.error('Failed to process webhook event:', processingError); 43 res.status(500).json({ error: 'Processing failed' }); 44 } 45 }); ``` * Python FastAPI ```python 1 from fastapi import FastAPI, Request, HTTPException 2 import os 3 import json 4 5 app = FastAPI() 6 7 @app.post("/webhook") 8 async def api_webhook(request: Request): 9 # Security: ALWAYS verify webhook signatures before processing events 10 # This prevents unauthorized webhook calls and replay attacks 11 12 raw_body = await request.body() 13 headers = { 14 "webhook-id": request.headers.get("webhook-id"), 15 "webhook-timestamp": request.headers.get("webhook-timestamp"), 16 "webhook-signature": request.headers.get("webhook-signature"), 17 } 18 19 try: 20 scalekit_client.verify_webhook_payload( 21 secret=os.getenv("SCALEKIT_WEBHOOK_SECRET"), 22 headers=headers, 23 payload=raw_body, 24 ) 25 except Exception as verification_error: 26 print(f"Webhook verification failed: {verification_error}") 27 raise HTTPException(status_code=401, detail="Webhook verification failed") 28 29 body = json.loads(raw_body.decode("utf-8")) 30 31 try: 32 event_type = body.get("type") 33 event_data = body.get("data", {}) 34 email = event_data.get("email") 35 name = event_data.get("name") 36 37 if event_type == "organization.directory.user_created": 38 await create_user_account(email, name) 39 elif event_type == "organization.directory.user_updated": 40 await update_user_account(email, name) 41 elif event_type == "organization.directory.user_deleted": 42 await deactivate_user_account(email) 43 44 return JSONResponse(status_code=201, content={"status": "processed"}) 45 46 except Exception as processing_error: 47 print(f"Failed to process webhook: {processing_error}") 48 raise HTTPException(status_code=500, detail="Event processing failed") ``` * Java Spring Boot ```java 1 @PostMapping("/webhook") 2 public ResponseEntity webhook( 3 @RequestBody String body, 4 @RequestHeader Map headers) { 5 6 // Security: ALWAYS verify webhook signatures before processing 7 // This prevents malicious webhook calls and protects against replay attacks 8 9 String secret = System.getenv("SCALEKIT_WEBHOOK_SECRET"); 10 11 Map verifyHeaders = new HashMap<>(); 12 verifyHeaders.put("webhook-id", headers.get("webhook-id")); 13 verifyHeaders.put("webhook-timestamp", headers.get("webhook-timestamp")); 14 verifyHeaders.put("webhook-signature", headers.get("webhook-signature")); 15 16 try { 17 // Java throws WebHookException. It does not return false. 18 scalekitClient.webhook() 19 .verifyWebhookPayload(secret, verifyHeaders, body.getBytes(java.nio.charset.StandardCharsets.UTF_8)); 20 } catch (Exception verificationError) { 21 System.err.println("Webhook verification failed: " + verificationError.getMessage()); 22 return ResponseEntity.badRequest().body("Webhook verification failed"); 23 } 24 25 try { 26 // Use case: Real-time user lifecycle management 27 // Examples: Employee onboarding, access termination, role modifications 28 ObjectMapper mapper = new ObjectMapper(); 29 JsonNode rootNode = mapper.readTree(body); 30 31 String eventType = rootNode.get("type").asText(); 32 JsonNode data = rootNode.get("data"); 33 34 switch (eventType) { 35 case "organization.directory.user_created": 36 String email = data.get("email").asText(); 37 String name = data.get("name").asText(); 38 createUserAccount(email, name); 39 break; 40 case "organization.directory.user_updated": 41 updateUserAccount(data); 42 break; 43 case "organization.directory.user_deleted": 44 deactivateUserAccount(data.get("email").asText()); 45 break; 46 default: 47 System.out.println("Unhandled event type: " + eventType); 48 } 49 50 return ResponseEntity.status(HttpStatus.CREATED).body("Webhook processed"); 51 52 } catch (Exception processingError) { 53 System.err.println("Failed to process webhook event: " + processingError.getMessage()); 54 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) 55 .body("Event processing failed"); 56 } 57 } ``` * Go Go ```go 1 // Security: Store webhook secret securely in environment variables 2 // Get this from Dashboard > Webhooks after registering your endpoint 3 webhookSecret := os.Getenv("SCALEKIT_WEBHOOK_SECRET") 4 5 http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) { 6 // Security: ALWAYS verify webhook signatures before processing events 7 // This prevents unauthorized webhook calls and replay attacks 8 9 if r.Method != http.MethodPost { 10 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 11 return 12 } 13 14 body, err := io.ReadAll(r.Body) 15 if err != nil { 16 http.Error(w, err.Error(), http.StatusBadRequest) 17 return 18 } 19 defer r.Body.Close() 20 21 // Extract webhook headers for verification 22 headers := map[string]string{ 23 "webhook-id": r.Header.Get("webhook-id"), 24 "webhook-signature": r.Header.Get("webhook-signature"), 25 "webhook-timestamp": r.Header.Get("webhook-timestamp"), 26 } 27 28 // Verify webhook signature to prevent malicious requests 29 valid, err := scalekitClient.VerifyWebhookPayload(webhookSecret, headers, body) 30 if err != nil || !valid { 31 http.Error(w, "Invalid webhook signature", http.StatusUnauthorized) 32 return 33 } 34 35 // Use case: Instant user provisioning and lifecycle management 36 // Examples: Real-time onboarding, emergency access revocation, role synchronization 37 var webhookEvent WebhookEvent 38 if err := json.Unmarshal(body, &webhookEvent); err != nil { 39 http.Error(w, "Invalid webhook payload", http.StatusBadRequest) 40 return 41 } 42 43 switch webhookEvent.Type { 44 case "organization.directory.user_created": 45 err = createUserAccount(webhookEvent.Data.Email, webhookEvent.Data.Name) 46 case "organization.directory.user_updated": 47 err = updateUserAccount(webhookEvent.Data) 48 case "organization.directory.user_deleted": 49 err = deactivateUserAccount(webhookEvent.Data.Email) 50 default: 51 fmt.Printf("Unhandled event type: %s\n", webhookEvent.Type) 52 } 53 54 if err != nil { 55 http.Error(w, "Failed to process webhook", http.StatusInternalServerError) 56 return 57 } 58 59 w.WriteHeader(http.StatusCreated) 60 w.Write([]byte(`{"status": "processed"}`)) 61 }) ``` 2. ### Register your webhook endpoint [Section titled “Register your webhook endpoint”](#register-your-webhook-endpoint) After implementing your secure webhook endpoint, register it in the Scalekit dashboard to start receiving events: 1. Navigate to **Dashboard > Webhooks** 2. Click **+Add Endpoint** 3. Enter your webhook endpoint URL (e.g., `https://your-app.com/api/webhooks/scalekit`) 4. Add a meaningful description for your reference 5. Select the event types you want to receive. Common choices include: * `organization.directory.user_created` - New user provisioning * `organization.directory.user_updated` - User profile changes * `organization.directory.user_deleted` - User deactivation * `organization.directory.group_created` - New group creation * `organization.directory.group_updated` - Group modifications Once registered, your webhook endpoint will start receiving event payloads from directory providers in real-time. 3. ### Process webhook events [Section titled “Process webhook events”](#process-webhook-events) Scalekit standardizes event payloads across different directory providers, ensuring consistent data structure regardless of whether your customers use Azure AD, Okta, Google Workspace, or other providers. When directory changes occur, Scalekit sends events with the following structure: Webhook event payload ```json 1 { 2 "id": "evt_1234567890", 3 "type": "organization.directory.user_created", 4 "data": { 5 "email": "john.doe@company.com", 6 "name": "John Doe", 7 "organization_id": "org_12345", 8 "directory_id": "dir_67890" 9 }, 10 "timestamp": "2024-01-15T10:30:00Z" 11 } ``` You have now successfully implemented and registered a webhook endpoint, enabling your application to receive real-time events for automated user provisioning. Your system can now respond instantly to directory changes, providing seamless user lifecycle management. Refer to our [webhook implementation guide](/authenticate/implement-workflows/implement-webhooks/) for the complete list of available event types and payload structures. --- # DOCUMENT BOUNDARY --- # Headless email API for magic link and OTP > Implement email OTP or magic link using direct API calls with full control over UX Implement magic link and OTP authentication using Scalekit’s headless APIs. Send either a one-time passcode (OTP) or a magic link to the user’s email, then verify their identity. Magic link and OTP offer two email-based authentication methods, clickable links or one-time passcodes, so users can sign in without passwords. You control the UI and user flows, while Scalekit provides the backend authentication infrastructure. Using a coding agent?Copy SaaSKit prompt *** 1. ## Set up Scalekit [Section titled “Set up Scalekit”](#set-up-scalekit) Install the Scalekit SDK to your project. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Your application is responsible for verifying users and initiating sessions, while Scalekit securely manages authentication tokens to ensure the verification process is completed successfully 2. ## Configure magic link and OTP settings [Section titled “Configure magic link and OTP settings”](#configure-magic-link-and-otp-settings) In the Scalekit dashboard, enable magic link and OTP and choose your login method. Optional security settings: * **Enforce same-browser origin**: Users must complete magic-link auth in the same browser they started in. * **Issue new credentials on resend**: Each resend generates a fresh code or link and invalidates the previous one. ![Scalekit dashboard Magic link & OTP settings showing the login method selection and expiry period fields](/.netlify/images?url=_astro%2F1.1jnMxeBv.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ## Send verification email [Section titled “Send verification email”](#send-verification-email) The first step in the magic link and OTP flow is to send a verification email to the user’s email address. This email contains either a **one-time passcode (OTP), a magic link, or both** based on your selection in the Scalekit dashboard. Follow these steps to implement the verification email flow: 1. Create a form to collect the user’s email address 2. Call the passwordless API (magic link and OTP) when the form is submitted 3. Handle the response to provide feedback to the user API endpoint ```http POST /api/v1/passwordless/email/send ``` **Example implementation** * cURL Send a verification code to user's email ```sh 1 curl -L '/api/v1/passwordless/email/send' \ 2 -H 'Content-Type: application/json' \ 3 -H 'Authorization: Bearer eyJh..' \ 4 --data-raw '{ 5 "email": "john.doe@example.com", 6 "expires_in": 300, 7 "state": "jAy-state1-gM4fdZ...2nqm6Q", 8 "template": "SIGNIN", 9 10 "magiclink_auth_uri": "https://yourapp.com/passwordless/verify", 11 "template_variables": { 12 "custom_variable_key": "custom_variable_value" 13 } 14 }' 15 16 # Response 17 # { 18 # "auth_request_id": "jAy-state1-gM4fdZ...2nqm6Q" 19 # "expires_at": "1748696575" 20 # "expires_in": 100 21 # "passwordless_type": "OTP" | "LINK" | "LINK_OTP" 22 # } ``` * Node.js ```js 1 const options = { 2 template: "SIGNIN", 3 state: "jAy-state1-...2nqm6Q", 4 expiresIn: 300, 5 // Required if you selected Link or Link+OTP as your authentication method 6 magiclinkAuthUri: "https://yourapp.com/passwordless/verify", 7 templateVariables: { 8 employeeID: "EMP523", 9 teamName: "Alpha Team", 10 }, 11 }; 12 13 const sendResponse = await scalekit.passwordless 14 .sendPasswordlessEmail( 15 "", 16 options 17 ); 18 19 // sendResponse = { 20 // authRequestId: string, 21 // expiresAt: number, // seconds since epoch 22 // expiresIn: number, // seconds 23 // passwordlessType: string // "OTP" | "LINK" | "LINK_OTP" 24 // } ``` * Python ```python 1 response = client.passwordless.send_passwordless_email( 2 email="john.doe@example.com", 3 template="SIGNIN", # or "SIGNUP", "UNSPECIFIED" 4 expires_in=300, 5 magiclink_auth_uri="https://yourapp.com/passwordless/verify", 6 template_variables={ 7 "employeeID": "EMP523", 8 "teamName": "Alpha Team", 9 }, 10 ) 11 12 # Extract auth request ID from response 13 auth_request_id = response[0].auth_request_id ``` * Go ```go 1 // Send a passwordless email (assumes you have an initialized `client` and `ctx`) 2 templateType := scalekit.TemplateTypeSignin 3 resp, err := scalekitClient.Passwordless().SendPasswordlessEmail( 4 ctx, 5 "john.doe@example.com", 6 &scalekit.SendPasswordlessOptions{ 7 Template: &templateType, 8 State: "jAy-state1-gM4fdZ...2nqm6Q", 9 ExpiresIn: 300, 10 MagiclinkAuthUri: "https://yourapp.com/passwordless/verify", // required if Link or Link+OTP 11 TemplateVariables: map[string]string{ 12 "employeeID": "EMP523", 13 "teamName": "Alpha Team", 14 }, 15 }, 16 ) 17 18 // resp contains: AuthRequestId, ExpiresAt, ExpiresIn, PasswordlessType ``` * Java ```java 1 import java.util.HashMap; 2 import java.util.Map; 3 4 TemplateType templateType = TemplateType.SIGNIN; 5 Map templateVariables = new HashMap<>(); 6 templateVariables.put("employeeID", "EMP523"); 7 templateVariables.put("teamName", "Alpha Team"); 8 9 SendPasswordlessOptions options = new SendPasswordlessOptions(); 10 options.setTemplate(templateType); 11 options.setExpiresIn(300); 12 options.setMagiclinkAuthUri("https://yourapp.com/passwordless/verify"); 13 options.setTemplateVariables(templateVariables); 14 15 SendPasswordlessResponse response = passwordlessClient.sendPasswordlessEmail( 16 "john.doe@example.com", 17 options 18 ); 19 20 String authRequestId = response.getAuthRequestId(); ``` 4. ### Resend a verification email [Section titled “Resend a verification email”](#resend-a-verification-email) Users can request a new verification email if they need one. Use the following endpoint to resend an OTP or magic link email. * cURL Request ```diff 1 curl -L '/api/v1/passwordless/email/resend' \ 2 -H 'Content-Type: application/json' \ 3 -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \ 4 -d '{ 5 "auth_request_id": "jAy-state1-gM4fdZ...2nqm6Q" 6 }' 7 8 # Response 9 10 # { 11 12 # "auth_request_id": "jAy-state1-gM4fdZ...2nqm6Q" 13 14 # "expires_at": "1748696575" 15 16 # "expires_in": 300 17 18 # "passwordless_type": "OTP" | "LINK" | "LINK_OTP" 19 20 # } ``` * Node.js ```js 1 const { authRequestId } = sendResponse; 2 const resendResponse = await scalekit.passwordless 3 .resendPasswordlessEmail( 4 authRequestId 5 ); 6 7 // resendResponse = { 8 // authRequestId: "jAy-state1-gM4fdZ...2nqm6Q", 9 // expiresAt: "1748696575", 10 // expiresIn: "300", 11 // passwordlessType: "OTP" | "LINK" | "LINK_OTP" 12 // } ``` * Python ```python 1 resend_response = client.passwordless.resend_passwordless_email( 2 auth_request_id=auth_request_id, 3 ) 4 5 new_auth_request_id = resend_response[0].auth_request_id ``` * Go ```go 1 // Resend passwordless email for an existing auth request 2 resendResp, err := scalekitClient.Passwordless().ResendPasswordlessEmail( 3 ctx, // context.Context (e.g., context.Background()) 4 authRequestId, // string: from the send email response 5 ) 6 7 if err != nil { 8 // handle error (log, return HTTP 400/500, etc.) 9 // ... 10 } 11 12 // resendResp is a pointer to ResendPasswordlessResponse struct: 13 // type ResendPasswordlessResponse struct { 14 // AuthRequestId string // Unique ID for the passwordless request 15 // ExpiresAt int64 // Unix timestamp (seconds since epoch) 16 // ExpiresIn int // Expiry duration in seconds 17 // PasswordlessType string // "OTP", "LINK", or "LINK_OTP" 18 // } ``` * Java ```java SendPasswordlessResponse resendResponse = passwordlessClient.resendPasswordlessEmail(authRequestId); ``` If you enabled **Enable new Magic link & OTP credentials on resend** in the Scalekit dashboard, a new verification code or magic link will be sent each time the user requests a new one. Rate limits Scalekit enforces a rate limit of 2 magic link and OTP emails per minute per email address. This limit includes both initial sends and resends. 5. ### Verify the user’s identity [Section titled “Verify the user’s identity”](#verify-the-users-identity) Once the user receives the verification email, * If it is a verification code, they’ll enter it in your application. Use the following endpoint to validate the code and complete authentication. * If it is a magic link, they’ll click the link in the email to verify their address. Capture the `link_token` query parameter and use it to verify. * For additional security with magic links, if you enabled “Enforce same browser origin” in the dashboard, include the `auth_request_id` in the verification request. - Verification code 1. Create a form to collect the verification code 2. Call the verification API when the form is submitted to verify the code 3. Handle the response to either grant access or show an error API endpoint ```http POST /api/v1/passwordless/email/verify ``` **Example implementation** * cURL Request ```diff curl -L '/api/v1/passwordless/email/verify' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \ -d '{ "code": "123456", "auth_request_id": "YC4QR-dVZVtNNVHcHwrnHNDV..." }' ``` * Node.js ```js 1 const { authRequestId } = sendResponse; 2 const verifyResponse = await scalekit.passwordless 3 .verifyPasswordlessEmail( 4 { code: "123456"}, 5 authRequestId 6 ); 7 8 // verifyResponse = { 9 // "email": "saifshine7@gmail.com", 10 // "state": "jAy-state1-gM4fdZdV22nqm6Q_j..", 11 // "template": "SIGNIN", 12 // "passwordless_type": "OTP" | "LINK" | "LINK_OTP" 13 // } ``` * Python ```python 1 verify_response = client.passwordless.verify_passwordless_email( 2 code="123456", # OTP code received via email 3 auth_request_id=auth_request_id, 4 ) 5 6 # User verified successfully 7 user_email = verify_response[0].email ``` * Go ```go 1 // Verify with OTP code 2 verifyResponse, err := scalekitClient.Passwordless().VerifyPasswordlessEmail( 3 ctx, 4 &scalekit.VerifyPasswordlessOptions{ 5 Code: "123456", // OTP code 6 AuthRequestId: authRequestId, 7 }, 8 ) 9 10 if err != nil { 11 // Handle error 12 return 13 } 14 15 // verifyResp contains the verified user's info 16 // type VerifyPasswordLessResponse struct { 17 // Email string 18 // State string 19 // Template string // SIGNIN | SIGNUP 20 // PasswordlessType string // OTP | LINK | LINK_OTP 21 // } ``` * Java ```java 1 // Verify with OTP code 2 VerifyPasswordlessOptions verifyOptions = new VerifyPasswordlessOptions(); 3 verifyOptions.setCode("123456"); // OTP code 4 verifyOptions.setAuthRequestId(authRequestId); 5 6 VerifyPasswordLessResponse verifyResponse = passwordlessClient.verifyPasswordlessEmail(verifyOptions); 7 8 // User verified successfully 9 String userEmail = verifyResponse.getEmail(); ``` - Magic link verification Request ```diff curl -L '/api/v1/passwordless/email/verify' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \ -d '{ "code": "123456", "auth_request_id": "YC4QR-dVZVtNNVHcHwrnHNDV..." }' ``` - cURL ```js 1 const { authRequestId } = sendResponse; 2 const verifyResponse = await scalekit.passwordless 3 .verifyPasswordlessEmail( 4 { code: "123456"}, 5 authRequestId 6 ); 7 8 // verifyResponse = { 9 // "email": "saifshine7@gmail.com", 10 // "state": "jAy-state1-gM4fdZdV22nqm6Q_j..", 11 // "template": "SIGNIN", 12 // "passwordless_type": "OTP" | "LINK" | "LINK_OTP" 13 // } ``` - Node.js ```python 1 verify_response = client.passwordless.verify_passwordless_email( 2 code="123456", # OTP code received via email 3 auth_request_id=auth_request_id, 4 ) 5 6 # User verified successfully 7 user_email = verify_response[0].email ``` - Python ```go 1 // Verify with OTP code 2 verifyResponse, err := scalekitClient.Passwordless().VerifyPasswordlessEmail( 3 ctx, 4 &scalekit.VerifyPasswordlessOptions{ 5 Code: "123456", // OTP code 6 AuthRequestId: authRequestId, 7 }, 8 ) 9 10 if err != nil { 11 // Handle error 12 return 13 } 14 15 // verifyResp contains the verified user's info 16 // type VerifyPasswordLessResponse struct { 17 // Email string 18 // State string 19 // Template string // SIGNIN | SIGNUP 20 // PasswordlessType string // OTP | LINK | LINK_OTP 21 // } ``` - Go ```java 1 // Verify with OTP code 2 VerifyPasswordlessOptions verifyOptions = new VerifyPasswordlessOptions(); 3 verifyOptions.setCode("123456"); // OTP code 4 verifyOptions.setAuthRequestId(authRequestId); 5 6 VerifyPasswordLessResponse verifyResponse = passwordlessClient.verifyPasswordlessEmail(verifyOptions); 7 8 // User verified successfully 9 String userEmail = verifyResponse.getEmail(); ``` - Java To support magic link verification, add a callback endpoint in your application typically at `https://your-app.com/passwordless/verify`. Implement it to verify the magic link token and complete the user authentication process. 1. Create a verification endpoint in your application to handle the magic link verification. This is the endpoint that the user lands in when they click the link in the email. 2. Capture the magic link token from the `link_token` request parameter from the URL. 3. Call the verification API when the user clicks the link in the email. 4. Based on token verification, complete the authentication process or show an error with an appropriate error message. API endpoint ```http POST /api/v1/passwordless/email/verify ``` **Example implementation** * cURL Request ```diff curl -L '/api/v1/passwordless/email/verify' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \ -d '{ "link_token": "a4143d8f-...c846ed91e_l", "auth_request_id": "YC4QR-dVZVtNNVHcHwrnHNDV..." // (optional) }' ``` * Node.js ```js 1 // User clicks the magic link in their email 2 // Example magic link: https://yourapp.com/passwordless/verify?link_token=a4143d8f-d13d-415c-8f5a-5a5c846ed91e_l 3 4 // 2. Express endpoint to handle the magic link verification 5 app.get('/passwordless/verify', async (req, res) => { 6 const { link_token } = req.query; 7 8 try { 9 // 3. Verify the magic link token with Scalekit 10 const verifyResponse = await scalekit.passwordless 11 .verifyPasswordlessEmail( 12 { linkToken: link_token }, 13 authRequestId // (optional) sendResponse.authRequestId 14 ); 15 16 // 4. Successfully log the user in 17 // Set session/token and redirect to dashboard 18 res.redirect('/dashboard'); 19 } catch (error) { 20 res.status(400).json({ 21 error: 'The magic link is invalid or has expired. Please request a new verification link.' 22 }); 23 } 24 }); 25 26 // verifyResponse = { 27 // "email": "saifshine7@gmail.com", 28 // "state": "jAy-state1-gM4fdZdV22nqm6Q_j..", 29 // "template": "SIGNIN", 30 // "passwordless_type": "OTP" | "LINK" | "LINK_OTP" 31 // } ``` * Python ```python 1 # Verify with magic link token 2 verify_response = client.passwordless.verify_passwordless_email( 3 link_token=link_token, # Magic link token from URL 4 # auth_request_id=auth_request_id, # optional if same-origin enforcement enabled 5 ) 6 7 # User verified successfully 8 user_email = verify_response[0].email ``` * Go ```go 1 verifyResponse, err := scalekitClient.Passwordless().VerifyPasswordlessEmail( 2 ctx, 3 &scalekit.VerifyPasswordlessOptions{ 4 LinkToken: linkToken, // Magic link token 5 }, 6 ) 7 8 if err != nil { 9 // Handle error 10 return 11 } 12 13 // User verified successfully 14 userEmail := verifyResponse.Email ``` * Java ```java 1 // Verify with magic link token 2 VerifyPasswordlessOptions verifyOptions = new VerifyPasswordlessOptions(); 3 verifyOptions.setLinkToken(linkToken); // Magic link token 4 // verifyOptions.setAuthRequestId(authRequestId); // optional if same-origin enforcement enabled 5 6 VerifyPasswordLessResponse verifyResponse = passwordlessClient.verifyPasswordlessEmail(verifyOptions); 7 8 // User verified successfully 9 String userEmail = verifyResponse.getEmail(); ``` - cURL Request ```diff curl -L '/api/v1/passwordless/email/verify' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \ -d '{ "link_token": "a4143d8f-...c846ed91e_l", "auth_request_id": "YC4QR-dVZVtNNVHcHwrnHNDV..." // (optional) }' ``` - Node.js ```js 1 // User clicks the magic link in their email 2 // Example magic link: https://yourapp.com/passwordless/verify?link_token=a4143d8f-d13d-415c-8f5a-5a5c846ed91e_l 3 4 // 2. Express endpoint to handle the magic link verification 5 app.get('/passwordless/verify', async (req, res) => { 6 const { link_token } = req.query; 7 8 try { 9 // 3. Verify the magic link token with Scalekit 10 const verifyResponse = await scalekit.passwordless 11 .verifyPasswordlessEmail( 12 { linkToken: link_token }, 13 authRequestId // (optional) sendResponse.authRequestId 14 ); 15 16 // 4. Successfully log the user in 17 // Set session/token and redirect to dashboard 18 res.redirect('/dashboard'); 19 } catch (error) { 20 res.status(400).json({ 21 error: 'The magic link is invalid or has expired. Please request a new verification link.' 22 }); 23 } 24 }); 25 26 // verifyResponse = { 27 // "email": "saifshine7@gmail.com", 28 // "state": "jAy-state1-gM4fdZdV22nqm6Q_j..", 29 // "template": "SIGNIN", 30 // "passwordless_type": "OTP" | "LINK" | "LINK_OTP" 31 // } ``` - Python ```python 1 # Verify with magic link token 2 verify_response = client.passwordless.verify_passwordless_email( 3 link_token=link_token, # Magic link token from URL 4 # auth_request_id=auth_request_id, # optional if same-origin enforcement enabled 5 ) 6 7 # User verified successfully 8 user_email = verify_response[0].email ``` - Go ```go 1 verifyResponse, err := scalekitClient.Passwordless().VerifyPasswordlessEmail( 2 ctx, 3 &scalekit.VerifyPasswordlessOptions{ 4 LinkToken: linkToken, // Magic link token 5 }, 6 ) 7 8 if err != nil { 9 // Handle error 10 return 11 } 12 13 // User verified successfully 14 userEmail := verifyResponse.Email ``` - Java ```java 1 // Verify with magic link token 2 VerifyPasswordlessOptions verifyOptions = new VerifyPasswordlessOptions(); 3 verifyOptions.setLinkToken(linkToken); // Magic link token 4 // verifyOptions.setAuthRequestId(authRequestId); // optional if same-origin enforcement enabled 5 6 VerifyPasswordLessResponse verifyResponse = passwordlessClient.verifyPasswordlessEmail(verifyOptions); 7 8 // User verified successfully 9 String userEmail = verifyResponse.getEmail(); ``` Validation attempt limits To protect your application, Scalekit allows a user only **five** attempts to enter the correct OTP within a ten-minute window. If the user exceeds this limit for an `auth_request_id`, the `/passwordless/email/verify` endpoint returns an **HTTP 429 Too Many Requests** error. To continue, the user must restart the authentication flow. You’ve successfully implemented Magic link & OTP authentication in your application. Users can now sign in securely without passwords by entering a verification code (OTP) or clicking a magic link sent to their email. --- # DOCUMENT BOUNDARY --- # Quickstart: Deploy Scalekit on Kubernetes > Deploy Scalekit on Kubernetes in minutes using bundled databases and a single values.yaml file. Get Scalekit running on Kubernetes quickly through the Scalekit distribution portal. This guide uses bundled PostgreSQL and Redis and auto-creates Kubernetes secrets from your `values.yaml`. No external databases or `kubectl secret` commands are needed. ## Before you start [Section titled “Before you start”](#before-you-start) | Requirement | Notes | | ----------------------- | -------------------------------------------------------------------------- | | `kubectl` 1.27+ | Configured against your target cluster | | Helm 3.12+ | Run `helm version` to verify | | Domain | Subdomains `app.` and `auth.` must resolve to your cluster | | Gateway class | A GatewayClass must be installed on your cluster | | TLS certificate | Attached via a gateway annotation (GCP cert map, cert-manager, etc.) | | SMTP credentials | Any provider; Postmark and SendGrid have first-class support | | Registry token | From the Scalekit distribution portal (see step 1) | | `openssl` and `python3` | To generate webhook credentials in step 2 | *** 1. ### Get a registry token [Section titled “Get a registry token”](#get-a-registry-token) Log in to the Scalekit distribution portal and create a Personal Access Token. This token authenticates your cluster to pull Scalekit images from the Scalekit container registry. Copy the token — it is shown only once. Note the expiry date and rotate before it lapses to avoid `ImagePullBackOff` errors on new deployments. 2. ### Generate webhook credentials [Section titled “Generate webhook credentials”](#generate-webhook-credentials) Run these commands to produce a JWT secret and a signed API token. Copy both output lines. You will paste them into `values.yaml` in the next step. ```bash 1 export JWT_SECRET=$(openssl rand -base64 32) 2 echo "jwtSecret: $JWT_SECRET" 3 4 python3 << 'EOF' 5 import base64, hashlib, hmac as _hmac, json, os, secrets, string, time 6 7 secret = os.environ['JWT_SECRET'] 8 chars = string.ascii_letters + string.digits 9 sub = 'org_' + ''.join(secrets.choice(chars) for _ in range(22)) 10 now = int(time.time()) 11 exp = now + 315360000 12 13 h = base64.urlsafe_b64encode(json.dumps({'alg':'HS256','typ':'JWT'}, separators=(',',':')).encode()).rstrip(b'=').decode() 14 p = base64.urlsafe_b64encode(json.dumps({'iat':now,'exp':exp,'nbf':now,'iss':'svix-server','sub':sub}, separators=(',',':')).encode()).rstrip(b'=').decode() 15 msg = f'{h}.{p}' 16 sig = base64.urlsafe_b64encode(_hmac.new(secret.encode(), msg.encode(), hashlib.sha256).digest()).rstrip(b'=').decode() 17 print(f'apiToken: {msg}.{sig}') 18 EOF ``` The output looks like: ```plaintext 1 jwtSecret: aB3cD4eF5gH6... 2 apiToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` 3. ### Create values.yaml [Section titled “Create values.yaml”](#create-valuesyaml) Create a `values.yaml` file using the template below. Replace each placeholder with your actual value. values.yaml ```yaml 1 scalekit: 2 config: 3 app: 4 domain: "" # e.g. scalekit.example.com — no scheme or trailing slash 5 seedData: 6 adminUser: 7 firstName: "" 8 lastName: "" 9 email: "" 10 emailServer: 11 settings: 12 fromEmail: "hi@" 13 fromName: "Team " 14 host: "" 15 port: 16 username: "" 17 18 postgresql: 19 enabled: true 20 21 redis: 22 enabled: true 23 24 secrets: 25 create: true 26 svix: 27 jwtSecret: "" 28 apiToken: "" 29 registry: 30 password: "" 31 32 gateway: 33 enabled: true 34 provider: "" # gcp for GKE; other for all other clusters 35 className: "" # e.g. gke-l7-global-external-managed 36 annotations: 37 : "" # e.g. networking.gke.io/certmap: your-cert-map 38 redirectToHttps: true 39 healthCheckPolicy: 40 enabled: true # GKE only — set false for other providers ``` | Field | Description | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `domain` | Base domain. The chart derives `app.` and `auth.` from this. | | `adminUser` | First admin account created on first boot. Use this to log in to the dashboard. | | `emailServer` | SMTP settings for transactional email (invites, magic links, verification codes). The password is provided separately via `secrets.smtp.password` (see [full configuration](/self-hosted/configuration/) for details). | | `secrets.create` | When `true`, the chart creates all required Kubernetes secrets from the values below. | | `secrets.svix` | Webhook service credentials generated in step 2. | | `secrets.registry.password` | Registry access token from step 1. | | `gateway.provider` | Set to `gcp` for GKE to enable GKE-specific resources. Set to `other` for all other providers. | | `gateway.className` | The GatewayClass installed on your cluster. | | `gateway.annotations` | Attach a TLS certificate via your provider’s annotation. | 4. ### Create a deployment in the portal [Section titled “Create a deployment in the portal”](#create-a-deployment-in-the-portal) Deployments are managed through the Scalekit distribution portal. Create the namespace on your cluster first: ```bash 1 kubectl create namespace ``` Then, in the portal: * In the left sidebar, click **Deployments**, then **+ New Deployment** * Select **Scalekit Onprem** and click **Continue** * Set a **Deployment Name** (`scalekit` is recommended) and enter the **Kubernetes Namespace** you just created * Leave **Enable cluster-scoped permissions** checked and click **Continue** * Select the **Version** you want to install * Under **Helm values**, paste the full contents of your `values.yaml` * Click **Create Deployment** The portal shows a **Deployment Created Successfully** screen with a `kubectl apply` command. Click **Copy Command** and run it on your cluster: ```bash 1 kubectl apply -n -f "" ``` This connects your cluster to the portal, which then installs the Helm chart and runs database migrations. 5. ### Update DNS [Section titled “Update DNS”](#update-dns) Once the gateway is provisioned, get its external IP: ```bash 1 kubectl get gateway -n scalekit ``` Copy the address from the `ADDRESS` column. In your DNS provider, create a wildcard `A` record: ```plaintext 1 *. ``` DNS propagation can take a few minutes. Verify with: ```bash 1 dig app. ``` 6. ### Verify [Section titled “Verify”](#verify) ```bash 1 kubectl get pods -n scalekit ``` All pods should show `Running`. Open `https://app.` in a browser and sign in with the admin email you set in `values.yaml`. ## Next steps [Section titled “Next steps”](#next-steps) Next, System requirements will confirm your cluster, databases, and network are ready before you proceed. * Ready for production? Switch to external databases and full secret management. Follow the [installation guide](/self-hosted/installation/). * Review every configuration field in the [configuration reference](/self-hosted/configuration/). * Learn how to upgrade and maintain your deployment in [Upgrades and maintenance](/self-hosted/upgrades/). Not for production The bundled databases have no backups, no replication, and no persistent storage guarantees. For a production deployment with external services and full secret management, follow the [installation guide](/self-hosted/installation/). --- # DOCUMENT BOUNDARY --- # Modular SSO quickstart > Enable enterprise SSO for any customer in minutes with built-in SAML and OIDC integrations Enterprise customers often require Single Sign-On (SSO) support for their applications. Rather than building custom integrations for every identity provider such as Okta, Entra ID, or JumpCloud and managing their OIDC and SAML protocols, you can let Scalekit handle those connections with each of your customer’s identity providers. Modular SSO is designed for applications that maintain their own user database and session management. This lightweight integration focuses solely on identity verification, giving you complete control over user data and authentication flows. Choose Modular SSO when you: * Want to manage user records in your own database * Prefer to implement custom session management logic * Need to integrate SSO without changing your existing authentication architecture * Already have existing user management infrastructure Using a coding agent?Copy SSO prompt 1. ## Set up Scalekit [Section titled “Set up Scalekit”](#set-up-scalekit) Use the following instructions to install the SDK for your technology stack. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Since we will using Modular SSO, you need to disable complete auth: 1. Go to Dashboard > Authentication > General 2. Under “Full-Stack Auth” section, click “Disable Full-Stack Auth” Now you’re ready to start integrating SSO into your app! 2. ## Redirect the users to their enterprise identity provider login page [Section titled “Redirect the users to their enterprise identity provider login page”](#redirect-the-users-to-their-enterprise-identity-provider-login-page) Use the Scalekit SDK to construct authorization URL with your redirect URI and required scopes. Scalekit will automatically redirect the user to the user’s enterprise identity provider login page to authenticate. * Node.js authorization-url.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new ScalekitClient( 4 '', // Your Scalekit environment URL 5 '', // Unique identifier for your app 6 '', 7 ); 8 9 const options = {}; 10 11 // Specify which SSO connection to use (choose one based on your use case) 12 // These identifiers are evaluated in order of precedence: 13 14 // 1. connectionId (highest precedence) - Use when you know the exact SSO connection 15 options['connectionId'] = 'conn_15696105471768821'; 16 17 // 2. organizationId - Routes to organization's SSO (useful for multi-tenant apps) 18 // If org has multiple connections, the first active one is selected 19 options['organizationId'] = 'org_15421144869927830'; 20 21 // 3. loginHint (lowest precedence) - Extracts domain from email to find connection 22 // Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 23 options['loginHint'] = 'user@example.com'; 24 25 // redirect_uri: Your callback endpoint that receives the authorization code 26 // Must match the URL registered in your Scalekit dashboard 27 const redirectUrl = 'https://your-app.com/auth/callback'; 28 29 const authorizationURL = scalekit.getAuthorizationUrl(redirectUrl, options); 30 // Redirect user to this URL to begin SSO authentication ``` * Python authorization\_url.py ```python 1 from scalekit import ScalekitClient, AuthorizationUrlOptions 2 3 scalekit = ScalekitClient( 4 '', # Your Scalekit environment URL 5 '', # Unique identifier for your app 6 '' 7 ) 8 9 options = AuthorizationUrlOptions() 10 11 # Specify which SSO connection to use (choose one based on your use case) 12 # These identifiers are evaluated in order of precedence: 13 14 # 1. connection_id (highest precedence) - Use when you know the exact SSO connection 15 options.connection_id = 'conn_15696105471768821' 16 17 # 2. organization_id - Routes to organization's SSO (useful for multi-tenant apps) 18 # If org has multiple connections, the first active one is selected 19 options.organization_id = 'org_15421144869927830' 20 21 # 3. login_hint (lowest precedence) - Extracts domain from email to find connection 22 # Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 23 options.login_hint = 'user@example.com' 24 25 # redirect_uri: Your callback endpoint that receives the authorization code 26 # Must match the URL registered in your Scalekit dashboard 27 redirect_uri = 'https://your-app.com/auth/callback' 28 29 authorization_url = scalekit_client.get_authorization_url( 30 redirect_uri=redirect_uri, 31 options=options 32 ) 33 # Redirect user to this URL to begin SSO authentication ``` * Go authorization\_url.go ```go 1 import ( 2 "github.com/scalekit-inc/scalekit-sdk-go" 3 ) 4 5 func main() { 6 scalekitClient := scalekit.NewScalekitClient( 7 "", // Your Scalekit environment URL 8 "", // Unique identifier for your app 9 "" 10 ) 11 12 options := scalekitClient.AuthorizationUrlOptions{} 13 14 // Specify which SSO connection to use (choose one based on your use case) 15 // These identifiers are evaluated in order of precedence: 16 17 // 1. ConnectionId (highest precedence) - Use when you know the exact SSO connection 18 options.ConnectionId = "conn_15696105471768821" 19 20 // 2. OrganizationId - Routes to organization's SSO (useful for multi-tenant apps) 21 // If org has multiple connections, the first active one is selected 22 options.OrganizationId = "org_15421144869927830" 23 24 // 3. LoginHint (lowest precedence) - Extracts domain from email to find connection 25 // Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 26 options.LoginHint = "user@example.com" 27 28 // redirectUrl: Your callback endpoint that receives the authorization code 29 // Must match the URL registered in your Scalekit dashboard 30 redirectUrl := "https://your-app.com/auth/callback" 31 32 authorizationURL := scalekitClient.GetAuthorizationUrl( 33 redirectUrl, 34 options, 35 ) 36 // Redirect user to this URL to begin SSO authentication 37 } ``` * Java AuthorizationUrl.java ```java 1 package com.scalekit; 2 3 import com.scalekit.ScalekitClient; 4 import com.scalekit.internal.http.AuthorizationUrlOptions; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 ScalekitClient scalekitClient = new ScalekitClient( 10 "", // Your Scalekit environment URL 11 "", // Unique identifier for your app 12 "" 13 ); 14 15 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 16 17 // Specify which SSO connection to use (choose one based on your use case) 18 // These identifiers are evaluated in order of precedence: 19 20 // 1. connectionId (highest precedence) - Use when you know the exact SSO connection 21 options.setConnectionId("con_13388706786312310"); 22 23 // 2. organizationId - Routes to organization's SSO (useful for multi-tenant apps) 24 // If org has multiple connections, the first active one is selected 25 options.setOrganizationId("org_13388706786312310"); 26 27 // 3. loginHint (lowest precedence) - Extracts domain from email to find connection 28 // Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 29 options.setLoginHint("user@example.com"); 30 31 // redirectUrl: Your callback endpoint that receives the authorization code 32 // Must match the URL registered in your Scalekit dashboard 33 String redirectUrl = "https://your-app.com/auth/callback"; 34 35 try { 36 String url = scalekitClient 37 .authentication() 38 .getAuthorizationUrl(redirectUrl, options) 39 .toString(); 40 // Redirect user to this URL to begin SSO authentication 41 } catch (Exception e) { 42 System.out.println(e.getMessage()); 43 } 44 } 45 } ``` * Direct URL (No SDK) OAuth2 authorization URL ```sh /oauth/authorize? response_type=code& # OAuth2 authorization code flow client_id=& # Your Scalekit client ID redirect_uri=& # URL-encoded callback URL scope=openid profile email& # "offline_access" is required to receive a refresh token organization_id=org_15421144869927830& # (Optional) Route by organization connection_id=conn_15696105471768821& # (Optional) Specific SSO connection login_hint=user@example.com # (Optional) Extract domain from email ``` **SSO identifiers** (choose one or more, evaluated in order of precedence): * `connection_id` - Direct to specific SSO connection (highest precedence) * `organization_id` - Route to organization’s SSO * `domain_hint` - Lookup connection by domain * `login_hint` - Extract domain from email (lowest precedence). Domain must be registered to the organization (manually via Dashboard or through admin portal when [onboarding an enterprise customer](/sso/guides/onboard-enterprise-customers/)) Example with actual values ```http https://tinotat-dev.scalekit.dev/oauth/authorize? response_type=code& client_id=skc_88036702639096097& redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback& scope=openid%20profile%20email& organization_id=org_15421144869927830 ``` Enterprise users see their identity provider’s login page. Users verify their identity through the authentication policies set by their organization’s administrator. Post successful verification, the user profile is [normalized](/sso/guides/user-profile-details/) and sent to your app. If your application needs to verify whether an SSO connection exists for a specific domain before proceeding, you can use the [list connections by domain SDK method](/guides/user-auth/check-sso-domain/). For details on how Scalekit determines which SSO connection to use, refer to the [SSO identifier precedence rules](/sso/guides/authorization-url/#parameter-precedence). 3. ## Get user details from the callback [Section titled “Get user details from the callback”](#get-user-details-from-the-callback) After successful authentication, Scalekit redirects to your callback URL with an authorization code. Your application exchanges this code for the user’s profile information and session tokens. 1. Add a callback endpoint in your application (typically `https://your-app.com/auth/callback`) 2. [Register](/guides/dashboard/redirects/#allowed-callback-urls) it in your Scalekit dashboard > Authentication > Redirect URLS > Allowed Callback URLs In authentication flow, Scalekit redirects to your callback URL with an authorization code. Your application exchanges this code for the user’s profile information. * Node.js Fetch user profile ```javascript 1 // Extract authentication parameters from the callback request 2 const { 3 code, 4 error, 5 error_description, 6 idp_initiated_login, 7 connection_id, 8 relay_state 9 } = req.query; 10 11 if (error) { 12 // Handle authentication errors returned from the identity provider 13 } 14 15 // Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 16 17 const result = await scalekit.authenticateWithCode(code, redirectUri); 18 const userEmail = result.user.email; 19 20 // Create a session for the authenticated user and grant appropriate access permissions ``` * Python Fetch user profile ```py 1 # Extract authentication parameters from the callback request 2 code = request.args.get('code') 3 error = request.args.get('error') 4 error_description = request.args.get('error_description') 5 idp_initiated_login = request.args.get('idp_initiated_login') 6 connection_id = request.args.get('connection_id') 7 relay_state = request.args.get('relay_state') 8 9 if error: 10 raise Exception(error_description) 11 12 # Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 13 14 result = scalekit.authenticate_with_code(code, '') 15 16 # Access normalized user profile information 17 user_email = result.user.email 18 19 # Create a session for the authenticated user and grant appropriate access permissions ``` * Go Fetch user profile ```go 1 // Extract authentication parameters from the callback request 2 code := r.URL.Query().Get("code") 3 error := r.URL.Query().Get("error") 4 errorDescription := r.URL.Query().Get("error_description") 5 idpInitiatedLogin := r.URL.Query().Get("idp_initiated_login") 6 connectionID := r.URL.Query().Get("connection_id") 7 relayState := r.URL.Query().Get("relay_state") 8 9 if error != "" { 10 // Handle authentication errors returned from the identity provider 11 } 12 13 // Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 14 15 result, err := scalekitClient.AuthenticateWithCode(r.Context(), code, redirectUrl) 16 17 if err != nil { 18 // Handle token exchange or validation errors 19 } 20 21 // Access normalized user profile information 22 userEmail := result.User.Email 23 24 // Create a session for the authenticated user and grant appropriate access permissions ``` * Java Fetch user profile ```java 1 // Extract authentication parameters from the callback request 2 String code = request.getParameter("code"); 3 String error = request.getParameter("error"); 4 String errorDescription = request.getParameter("error_description"); 5 String idpInitiatedLogin = request.getParameter("idp_initiated_login"); 6 String connectionID = request.getParameter("connection_id"); 7 String relayState = request.getParameter("relay_state"); 8 9 if (error != null && !error.isEmpty()) { 10 // Handle authentication errors returned from the identity provider 11 return; 12 } 13 14 // Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 15 16 try { 17 AuthenticationResponse result = scalekit.authentication().authenticateWithCode(code, redirectUrl); 18 String userEmail = result.getIdTokenClaims().getEmail(); 19 20 // Create a session for the authenticated user and grant appropriate access permissions 21 } catch (Exception e) { 22 // Handle token exchange or validation errors 23 } ``` The `result` object * Node.js Validate tokens ```js 1 // Validate and decode the ID token from the authentication result 2 const idTokenClaims = await scalekit.validateToken(result.idToken); 3 4 // Validate and decode the access token 5 const accessTokenClaims = await scalekit.validateToken(result.accessToken); ``` * Python Validate tokens ```py 1 # Validate and decode the ID token from the authentication result 2 id_token_claims = scalekit_client.validate_token(result["id_token"]) 3 4 # Validate and decode the access token 5 access_token_claims = scalekit_client.validate_token(result["access_token"]) ``` * Go Validate tokens ```go 1 // Create a background context for the API call 2 ctx := context.Background() 3 4 // Validate and decode the access token (uses JWKS from the client) 5 accessTokenClaims, err := scalekitClient.GetAccessTokenClaims(ctx, result.AccessToken) 6 if err != nil { 7 // handle error 8 } ``` * Java Validate tokens ```java 1 // Validate and decode the ID token 2 Map idTokenClaims = scalekitClient.validateToken(result.getIdToken()); 3 4 // Validate and decode the access token 5 Map accessTokenClaims = scalekitClient.validateToken(result.getAccessToken()); ``` - Auth result ```js 1 { 2 user: { 3 email: 'john@example.com', 4 familyName: 'Doe', 5 givenName: 'John', 6 username: 'john@example.com', 7 id: 'conn_70087756662964366;dcc62570-6a5a-4819-b11b-d33d110c7716' 8 }, 9 idToken: 'eyJhbGciOiJSU..bcLQ', 10 accessToken: 'eyJhbGciO..', 11 expiresIn: 899 12 } ``` - ID token (decoded) ```js 1 { 2 iss: '', // Issuer: Scalekit environment URL (must match your environment) 3 aud: [ 'skc_70087756327420046' ], // Audience: Your client ID (must match for validation) 4 azp: 'skc_70087756327420046', // Authorized party: Usually same as aud 5 sub: 'conn_70087756662964366;e964d135-35c7-4a13-a3b4-2579a1cdf4e6', // Subject: Connection ID and IdP user ID (SSO-specific format) 6 oid: 'org_70087756646187150', // Organization ID: User's organization 7 exp: 1758952038, // Expiration: Unix timestamp (validate token hasn't expired) 8 iat: 1758692838, // Issued at: Unix timestamp when token was issued 9 at_hash: 'yMGIBg7BkmIGgD6_dZPEGQ', // Access token hash: For token binding validation 10 c_hash: '4x7qsXnlRw6dRC6twnuENw', // Authorization code hash: For code binding validation 11 amr: [ 'conn_70087756662964366' ], // Authentication method reference: SSO connection ID used for authentication 12 email: 'john@example.com', // User's email address 13 preferred_username: 'john@example.com', // Preferred username (often same as email for SSO) 14 family_name: 'Doe', // User's last name 15 given_name: 'John', // User's first name 16 sid: 'ses_91646612652163629', // Session ID: Links token to user session 17 client_id: 'skc_70087756327420046' // Client ID: Your application identifier 18 } ``` - Access token (decoded) ```js 1 { 2 "iss": "", // Issuer: Scalekit environment URL (must match your environment) 3 "aud": ["skc_70087756327420046"], // Audience: Your client ID (must match for validation) 4 "sub": "conn_70087756662964366;dcc62570-6a5a-4819-b11b-d33d110c7716", // Subject: Connection ID and IdP user ID (SSO-specific format) 5 "exp": 1758693916, // Expiration: Unix timestamp (validate token hasn't expired) 6 "iat": 1758693016, // Issued at: Unix timestamp when token was issued 7 "nbf": 1758693016, // Not before: Unix timestamp (token valid from this time) 8 "jti": "tkn_91646913048216109", // JWT ID: Unique token identifier 9 "client_id": "skc_70087756327420046" // Client ID: Your application identifier 10 } ``` 4. ## Handle IdP-initiated SSO Recommended [Section titled “Handle IdP-initiated SSO ”](#handle-idp-initiated-sso-) When users start the login process from their identity provider’s portal (rather than your application), this is called IdP-initiated SSO. Scalekit converts these requests to secure SP-initiated flows automatically. Your initiate login endpoint receives an `idp_initiated_login` JWT parameter containing the user’s organization and connection details. Decode this token and generate a new authorization URL to complete the authentication flow securely. ```sh https://yourapp.com/login?idp_initiated_login= ``` Configure your initiate login endpoint in [Dashboard > Authentication > Redirects](/guides/dashboard/redirects/#initiate-login-url) * Node.js handle-idp-initiated.js ```javascript 1 // Your initiate login endpoint receives the IdP-initiated login token 2 const { idp_initiated_login, error, error_description } = req.query; 3 4 if (error) { 5 return res.status(400).json({ message: error_description }); 6 } 7 8 // When users start login from their IdP portal, convert to SP-initiated flow 9 if (idp_initiated_login) { 10 // Decode the JWT to extract organization and connection information 11 const claims = await scalekit.getIdpInitiatedLoginClaims(idp_initiated_login); 12 13 const options = { 14 connectionId: claims.connection_id, // Specific SSO connection 15 organizationId: claims.organization_id, // User's organization 16 loginHint: claims.login_hint, // User's email for context 17 state: claims.relay_state // Preserve state from IdP 18 }; 19 20 // Generate authorization URL and redirect to complete authentication 21 const authorizationURL = scalekit.getAuthorizationUrl( 22 'https://your-app.com/auth/callback', 23 options 24 ); 25 26 return res.redirect(authorizationURL); 27 } ``` * Python handle\_idp\_initiated.py ```python 1 # Your initiate login endpoint receives the IdP-initiated login token 2 idp_initiated_login = request.args.get('idp_initiated_login') 3 error = request.args.get('error') 4 error_description = request.args.get('error_description') 5 6 if error: 7 raise Exception(error_description) 8 9 # When users start login from their IdP portal, convert to SP-initiated flow 10 if idp_initiated_login: 11 # Decode the JWT to extract organization and connection information 12 claims = await scalekit.get_idp_initiated_login_claims(idp_initiated_login) 13 14 options = AuthorizationUrlOptions() 15 options.connection_id = claims.get('connection_id') # Specific SSO connection 16 options.organization_id = claims.get('organization_id') # User's organization 17 options.login_hint = claims.get('login_hint') # User's email for context 18 options.state = claims.get('relay_state') # Preserve state from IdP 19 20 # Generate authorization URL and redirect to complete authentication 21 authorization_url = scalekit.get_authorization_url( 22 redirect_uri='https://your-app.com/auth/callback', 23 options=options 24 ) 25 26 return redirect(authorization_url) ``` * Go handle\_idp\_initiated.go ```go 1 // Your initiate login endpoint receives the IdP-initiated login token 2 idpInitiatedLogin := r.URL.Query().Get("idp_initiated_login") 3 errorDesc := r.URL.Query().Get("error_description") 4 5 if errorDesc != "" { 6 http.Error(w, errorDesc, http.StatusBadRequest) 7 return 8 } 9 10 // When users start login from their IdP portal, convert to SP-initiated flow 11 if idpInitiatedLogin != "" { 12 // Decode the JWT to extract organization and connection information 13 claims, err := scalekitClient.GetIdpInitiatedLoginClaims(r.Context(), idpInitiatedLogin) 14 if err != nil { 15 http.Error(w, err.Error(), http.StatusInternalServerError) 16 return 17 } 18 19 options := scalekit.AuthorizationUrlOptions{ 20 ConnectionId: claims.ConnectionID, // Specific SSO connection 21 OrganizationId: claims.OrganizationID, // User's organization 22 LoginHint: claims.LoginHint, // User's email for context 23 } 24 25 // Generate authorization URL and redirect to complete authentication 26 authUrl, err := scalekitClient.GetAuthorizationUrl( 27 "https://your-app.com/auth/callback", 28 options 29 ) 30 31 if err != nil { 32 http.Error(w, err.Error(), http.StatusInternalServerError) 33 return 34 } 35 36 http.Redirect(w, r, authUrl.String(), http.StatusFound) 37 } ``` * Java HandleIdpInitiated.java ```java 1 // Your initiate login endpoint receives the IdP-initiated login token 2 @GetMapping("/login") 3 public RedirectView handleInitiateLogin( 4 @RequestParam(required = false, name = "idp_initiated_login") String idpInitiatedLoginToken, 5 @RequestParam(required = false) String error, 6 @RequestParam(required = false, name = "error_description") String errorDescription, 7 HttpServletResponse response) throws IOException { 8 9 if (error != null) { 10 response.sendError(HttpStatus.BAD_REQUEST.value(), errorDescription); 11 return null; 12 } 13 14 // When users start login from their IdP portal, convert to SP-initiated flow 15 if (idpInitiatedLoginToken != null) { 16 // Decode the JWT to extract organization and connection information 17 IdpInitiatedLoginClaims claims = scalekit 18 .authentication() 19 .getIdpInitiatedLoginClaims(idpInitiatedLoginToken); 20 21 if (claims == null) { 22 response.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid token"); 23 return null; 24 } 25 26 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 27 options.setConnectionId(claims.getConnectionID()); // Specific SSO connection 28 options.setOrganizationId(claims.getOrganizationID()); // User's organization 29 options.setLoginHint(claims.getLoginHint()); // User's email for context 30 31 // Generate authorization URL and redirect to complete authentication 32 String authUrl = scalekit 33 .authentication() 34 .getAuthorizationUrl("https://your-app.com/auth/callback", options) 35 .toString(); 36 37 response.sendRedirect(authUrl); 38 return null; 39 } 40 41 return null; 42 } ``` This approach provides enhanced security by converting IdP-initiated requests to standard SP-initiated flows, protecting against SAML assertion theft and replay attacks. Learn more: [IdP-initiated SSO implementation guide](/sso/guides/idp-init-sso/) 5. ## Test your SSO integration [Section titled “Test your SSO integration”](#test-your-sso-integration) Validate your implementation using the **IdP Simulator** and **Test Organization** included in your development environment. Test all three scenarios before deploying to production. Your environment includes a pre-configured test organization (found in **Dashboard > Organizations**) with domains like `@example.com` and `@example.org` for testing. Pass one of the following connection selectors in your authorization URL: * Email address with `@example.com` or `@example.org` domain * Test organization’s connection ID * Organization ID This opens the SSO login page (IdP Simulator) that simulates your customer’s identity provider login experience. ![IdP Simulator](/.netlify/images?url=_astro%2F2.1.BEM1Vo-J.png\&w=2646\&h=1652\&dpl=6aaa70ad2ea7b40008ad2afd) For detailed testing instructions and scenarios, see our [Complete SSO testing guide](/sso/guides/test-sso/) 6. ## Set up SSO with your existing authentication system [Section titled “Set up SSO with your existing authentication system”](#set-up-sso-with-your-existing-authentication-system) Many applications already use an authentication provider such as Auth0, Firebase, or AWS Cognito. To enable single sign-on (SSO) using Scalekit, configure Scalekit to work with your current authentication provider. ### Auth0 Integrate Scalekit with Auth0 for enterprise SSO [Know more →](/guides/integrations/auth-systems/auth0) ### Firebase Auth Add enterprise authentication to Firebase projects [Know more →](/guides/integrations/auth-systems/firebase) ### AWS Cognito Configure Scalekit with AWS Cognito user pools [Know more →](/guides/integrations/auth-systems/aws-cognito) 7. ## Onboard enterprise customers [Section titled “Onboard enterprise customers”](#onboard-enterprise-customers) Enable SSO for your enterprise customers by creating an organization in Scalekit and providing them access to the Admin Portal. Your customers configure their identity provider settings themselves through a self-service portal. **Create an organization** for your customer in [Dashboard > Organizations](https://app.scalekit.com/organizations), then provide Admin Portal access using one of these methods: * Shareable link Generate a secure link your customer can use to access the Admin Portal: generate-portal-link.js ```javascript // Generate a one-time Admin Portal link for your customer const portalLink = await scalekit.organization.generatePortalLink( 'org_32656XXXXXX0438' // Your customer's organization ID ); // Share this link with your customer's IT admin via email or messaging // Example: '/magicLink/8930509d-68cf-4e2c-8c6d-94d2b5e2db43 console.log('Admin Portal URL:', portalLink.location); ``` Send this link to your customer’s IT administrator through email, Slack, or your preferred communication channel. They can configure their SSO connection without any developer involvement. * Embedded portal Embed the Admin Portal directly in your application using an iframe: embed-portal.js ```javascript // Generate a secure portal link at runtime const portalLink = await scalekit.organization.generatePortalLink(orgId); // Return the link to your frontend to embed in an iframe res.json({ portalUrl: portalLink.location }); ``` admin-settings.html ```html ``` Customers configure SSO without leaving your application, maintaining a consistent user experience. Learn more: [Embedded Admin Portal guide](/guides/admin-portal/#embed-the-admin-portal) **Enable domain verification** for seamless user experience. Once your customer verifies their domain (e.g., `@megacorp.org`), users can sign in without selecting their organization. Scalekit automatically routes them to the correct identity provider based on their email domain. **Pre-check SSO availability** before redirecting users. This prevents failed redirects when a user’s domain doesn’t have SSO configured: * Node.js check-sso-availability.js ```javascript 1 // Extract domain from user's email address 2 const domain = email.split('@')[1].toLowerCase(); // e.g., "megacorp.org" 3 4 // Check if domain has an active SSO connection 5 const { connections } = await scalekit.connection.listConnectionsByDomain(domain); 6 7 if (connections.length > 0) { 8 // Domain has SSO configured - redirect to identity provider 9 const authUrl = scalekit.getAuthorizationUrl(redirectUri, { 10 domainHint: domain // Automatically routes to correct IdP 11 }); 12 return res.redirect(authUrl); 13 } else { 14 // No SSO for this domain - show alternative login methods 15 return showPasswordlessLogin(); 16 } ``` * Python check\_sso\_availability.py ```python 1 # Extract domain from user's email address 2 domain = email.split('@')[1].lower() # e.g., "megacorp.org" 3 4 # Check if domain has an active SSO connection 5 connections = scalekit_client.connection.list_connections_by_domain(domain=domain).connections 6 7 if len(connections) > 0: 8 # Domain has SSO configured - redirect to identity provider 9 options = AuthorizationUrlOptions() 10 options.domain_hint = domain # Automatically routes to correct IdP 11 12 auth_url = scalekit_client.get_authorization_url( 13 redirect_uri=redirect_uri, 14 options=options 15 ) 16 return redirect(auth_url) 17 else: 18 # No SSO for this domain - show alternative login methods 19 return show_passwordless_login() ``` * Go check\_sso\_availability.go ```go 1 // Extract domain from user's email address 2 parts := strings.Split(email, "@") 3 domain := strings.ToLower(parts[1]) // e.g., "megacorp.org" 4 5 // Check if domain has an active SSO connection 6 connections, err := scalekitClient.Connections.ListConnectionsByDomain(domain) 7 if err != nil { 8 // Handle error 9 return err 10 } 11 12 if len(connections) > 0 { 13 // Domain has SSO configured - redirect to identity provider 14 options := scalekit.AuthorizationUrlOptions{ 15 DomainHint: domain, // Automatically routes to correct IdP 16 } 17 18 authUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options) 19 if err != nil { 20 return err 21 } 22 23 c.Redirect(http.StatusFound, authUrl.String()) 24 } else { 25 // No SSO for this domain - show alternative login methods 26 return showPasswordlessLogin() 27 } ``` * Java CheckSsoAvailability.java ```java 1 // Extract domain from user's email address 2 String[] parts = email.split("@"); 3 String domain = parts[1].toLowerCase(); // e.g., "megacorp.org" 4 5 // Check if domain has an active SSO connection 6 List connections = scalekitClient 7 .connections() 8 .listConnectionsByDomain(domain); 9 10 if (connections.size() > 0) { 11 // Domain has SSO configured - redirect to identity provider 12 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 13 options.setDomainHint(domain); // Automatically routes to correct IdP 14 15 String authUrl = scalekitClient 16 .authentication() 17 .getAuthorizationUrl(redirectUri, options) 18 .toString(); 19 20 return new RedirectView(authUrl); 21 } else { 22 // No SSO for this domain - show alternative login methods 23 return showPasswordlessLogin(); 24 } ``` This check ensures users only see SSO options when available, improving the login experience and reducing confusion. --- # DOCUMENT BOUNDARY --- # AgentKit code samples > Full working examples showing how to integrate AgentKit with popular AI frameworks and agent platforms. Each example builds a working agent that reads a user’s Gmail inbox using Scalekit-authenticated tools. ## No agent loop to build [Section titled “No agent loop to build”](#no-agent-loop-to-build) These platforms manage the agent harness for you. Pass a Scalekit skill or MCP URL, describe the task, and the platform handles tool discovery, execution, and session state. [Claude Managed Agents](/agentkit/examples/claude-managed-agents/)Anthropic runs the agent loop. Pass a Scalekit MCP URL, describe a task, and Claude handles tool discovery, execution, and retries. [OpenClaw](/agentkit/openclaw/)Conversational agent platform. No code required to connect 200+ services including Gmail, Slack, Notion, and LinkedIn. [Hermes](/agentkit/hermes/)Nous Research agent runtime. Install a Scalekit skill and act as a named user in Gmail, Slack, and other apps. [Hermes example repo](https://github.com/scalekit-developers/hermes-agentkit-example)Companion repo for the Hermes how-to. Install hermes-delegated-auth and run one GitHub read as an opaque identifier. ## Build your own agent loop [Section titled “Build your own agent loop”](#build-your-own-agent-loop) These integrations give you full control. Fetch Scalekit tool schemas, wire them into your framework, and run the tool-use loop yourself. | Framework | Language | Integration | Notes | | ---------------------------------------------- | --------------- | -------------------- | -------------------------------------------------------------------------------- | | [LangChain](/agentkit/examples/langchain/) | Python | SDK, native adapter | Scalekit returns native LangChain tool objects. No schema reshaping needed. | | [Google ADK](/agentkit/examples/google-adk/) | Python | SDK, native adapter | Scalekit returns native ADK tool objects. No schema reshaping needed. | | [Anthropic](/agentkit/examples/anthropic/) | Python, Node.js | SDK, direct | Tool schemas use `input_schema`, which matches Anthropic’s format exactly. | | [OpenAI](/agentkit/examples/openai/) | Python, Node.js | SDK, direct | Rename `input_schema` to `parameters` to match OpenAI’s function format. | | [Vercel AI SDK](/agentkit/examples/vercel-ai/) | Node.js | SDK, `tool()` helper | Wrap tools with `tool()` and `jsonSchema()`. No manual schema conversion needed. | | [CrewAI](/agentkit/examples/crewai/) | Python | MCP | `MCPServerAdapter` connects to a Scalekit MCP URL. Tool discovery is automatic. | | [Mastra](/agentkit/examples/mastra/) | Node.js | MCP | Native MCP support via `@mastra/mcp`. Tool discovery is automatic. | ## Working examples on GitHub [Section titled “Working examples on GitHub”](#working-examples-on-github) ### [Connect LangChain agents to Gmail](https://github.com/scalekit-inc/sample-langchain-agent) [Securely connect a LangChain agent to Gmail using Scalekit for authentication. Python example for tool authorization.](https://github.com/scalekit-inc/sample-langchain-agent) ### [Connect Google GenAI agents to Gmail](https://github.com/scalekit-inc/google-adk-agent-example) [Build a Google ADK agent that securely accesses Gmail tools. Python example demonstrating Scalekit auth integration.](https://github.com/scalekit-inc/google-adk-agent-example) ### [Connect agents to Slack tools](https://github.com/scalekit-inc/python-connect-demos/tree/main/direct) [Authorize Python agents to use Slack tools with Scalekit. Direct integration example for secure tool access.](https://github.com/scalekit-inc/python-connect-demos/tree/main/direct) ### [Connect CrewAI agents to Gmail](https://github.com/scalekit-developers/crewai-scalekit-example) [Multi-agent email triage crew using CrewAI with Scalekit-authenticated Gmail tools via MCP.](https://github.com/scalekit-developers/crewai-scalekit-example) ### [Meeting prep agent](https://github.com/scalekit-inc/meeting-prep-agent-example) [Pulls context from Google Cal, Gmail, HubSpot, and Slack before each external meeting. Delivers a structured brief in under 60 seconds using delegated user identity.](https://github.com/scalekit-inc/meeting-prep-agent-example) ### [Browse all agent auth examples](https://github.com/scalekit-developers/agent-auth-examples) [A curated collection of working examples showing how to build agents that authenticate and access tools using Scalekit.](https://github.com/scalekit-developers/agent-auth-examples) --- # DOCUMENT BOUNDARY --- # Anthropic > Build an Anthropic agent with Scalekit-authenticated tools. Scalekit returns tool schemas in Anthropic's native format; no conversion needed. Build an agent using Anthropic’s Claude that reads a user’s Gmail inbox. Scalekit returns tool schemas with `input_schema`, the exact format Anthropic’s tool use API expects. ## Install [Section titled “Install”](#install) * Python ```sh 1 pip install scalekit-sdk-python anthropic ``` * Node.js ```sh 1 npm install @scalekit-sdk/node @anthropic-ai/sdk ``` ## Initialize [Section titled “Initialize”](#initialize) * Python ```python 1 import os 2 import scalekit.client 3 import anthropic 4 from google.protobuf.json_format import MessageToDict 5 6 scalekit_client = scalekit.client.ScalekitClient( 7 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 8 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 9 env_url=os.getenv("SCALEKIT_ENV_URL"), 10 ) 11 actions = scalekit_client.actions 12 client = anthropic.Anthropic() ``` * Node.js ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; 3 import Anthropic from '@anthropic-ai/sdk'; 4 5 const scalekit = new ScalekitClient( 6 process.env.SCALEKIT_ENV_URL!, 7 process.env.SCALEKIT_CLIENT_ID!, 8 process.env.SCALEKIT_CLIENT_SECRET!, 9 ); 10 const anthropic = new Anthropic(); ``` ## Connect the user to Gmail [Section titled “Connect the user to Gmail”](#connect-the-user-to-gmail) * Python ```python 1 response = actions.get_or_create_connected_account( 2 connection_name="gmail", 3 identifier="user_123", 4 ) 5 if response.connected_account.status != "ACTIVE": 6 link = actions.get_authorization_link(connection_name="gmail", identifier="user_123") 7 print("Authorize Gmail:", link.link) 8 input("Press Enter after authorizing...") ``` * Node.js ```typescript 1 const { connectedAccount } = await scalekit.actions.getOrCreateConnectedAccount({ 2 connectionName: 'gmail', 3 identifier: 'user_123', 4 }); 5 if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { 6 const { link } = await scalekit.actions.getAuthorizationLink({ connectionName: 'gmail', identifier: 'user_123' }); 7 console.log('Authorize Gmail:', link); 8 } ``` See [Authorize a user](/agentkit/tools/authorize/) for production auth handling. ## Run the agent [Section titled “Run the agent”](#run-the-agent) Fetch tools scoped to this user, then run the full Claude tool-use loop: * Python ```python 1 # Fetch tools scoped to this user 2 scoped_response, _ = actions.tools.list_scoped_tools( 3 identifier="user_123", 4 filter={"connection_names": ["gmail"]}, 5 page_size=100, # fetch beyond the default page so no connector tools are missed 6 ) 7 llm_tools = [ 8 { 9 "name": MessageToDict(t.tool).get("definition", {}).get("name"), 10 "description": MessageToDict(t.tool).get("definition", {}).get("description", ""), 11 "input_schema": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}), 12 } 13 for t in scoped_response.tools 14 ] 15 16 # Run the agent loop 17 messages = [{"role": "user", "content": "Fetch my last 5 unread emails and summarize them"}] 18 19 while True: 20 response = client.messages.create( 21 model="claude-sonnet-4-6", 22 max_tokens=1024, 23 tools=llm_tools, 24 messages=messages, 25 ) 26 if response.stop_reason == "end_turn": 27 print(response.content[0].text) 28 break 29 30 tool_results = [] 31 for block in response.content: 32 if block.type == "tool_use": 33 result = actions.execute_tool( 34 tool_name=block.name, 35 identifier="user_123", 36 tool_input=block.input, 37 ) 38 tool_results.append({ 39 "type": "tool_result", 40 "tool_use_id": block.id, 41 "content": str(result.data), 42 }) 43 44 messages.append({"role": "assistant", "content": response.content}) 45 messages.append({"role": "user", "content": tool_results}) ``` * Node.js ```typescript 1 // Fetch tools scoped to this user 2 const { tools } = await scalekit.tools.listScopedTools('user_123', { 3 filter: { connectionNames: ['gmail'] }, 4 pageSize: 100, // fetch beyond the default page so no connector tools are missed 5 }); 6 const llmTools = tools.map(t => ({ 7 name: t.tool.definition.name, 8 description: t.tool.definition.description, 9 input_schema: t.tool.definition.input_schema, 10 })); 11 12 // Run the agent loop 13 const messages: Anthropic.MessageParam[] = [ 14 { role: 'user', content: 'Fetch my last 5 unread emails and summarize them' }, 15 ]; 16 17 while (true) { 18 const response = await anthropic.messages.create({ 19 model: 'claude-sonnet-4-6', 20 max_tokens: 1024, 21 tools: llmTools, 22 messages, 23 }); 24 25 if (response.stop_reason === 'end_turn') { 26 const text = response.content.find(b => b.type === 'text'); 27 if (text?.type === 'text') console.log(text.text); 28 break; 29 } 30 31 const toolResults: Anthropic.ToolResultBlockParam[] = []; 32 for (const block of response.content) { 33 if (block.type === 'tool_use') { 34 const result = await scalekit.actions.executeTool({ 35 toolName: block.name, 36 identifier: 'user_123', 37 toolInput: block.input as Record, 38 }); 39 toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(result.data) }); 40 } 41 } 42 messages.push({ role: 'assistant', content: response.content }); 43 messages.push({ role: 'user', content: toolResults }); 44 } ``` ## Use MCP instead [Section titled “Use MCP instead”](#use-mcp-instead) Claude Desktop and other Anthropic-compatible MCP hosts connect directly to Scalekit MCP URLs. Add the URL to your MCP host config: ```json 1 { 2 "mcpServers": { 3 "scalekit": { 4 "transport": "streamable-http", 5 "url": "your-scalekit-mcp-url" 6 } 7 } 8 } ``` For programmatic use, connect via any MCP client library and pass tools to `anthropic.messages.create`. See [Virtual MCP Servers](/agentkit/mcp/overview/) for setup details and the URL. --- # DOCUMENT BOUNDARY --- # Claude Managed Agents > Run Claude Managed Agents with Scalekit-authenticated tools using Virtual MCP Servers and Anthropic vaults. Run a background agent that reads Gmail and creates Google Calendar events — without managing any agent loop. Anthropic handles tool discovery, execution, retries, and session state. You provide the task. Scalekit connects the agent to user-authorized tools via a [Virtual MCP Server](/agentkit/mcp/overview/). Before each run, you mint a short-lived session token and store it in an Anthropic vault. The agent accesses the MCP server using the vault credential. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A Scalekit account with Gmail and Google Calendar connections configured. See [Configure a connection](/agentkit/connections/). * An [Anthropic API key](https://platform.anthropic.com/settings/keys) with access to the Managed Agents beta. * An Anthropic environment ID set as `ANTHROPIC_ENVIRONMENT_ID`. ## How it works [Section titled “How it works”](#how-it-works) The flow has three phases: 1. **Build** (one-time) — Create a Virtual MCP Server and a Claude Managed Agent. Save `mcp_id` and `agent_id`. 2. **Authorize user for external connections** (once per user) — Authorize the user’s Gmail and Google Calendar accounts. 3. **Run a session** (per agent run) — Check connections, mint a session token, store it in an Anthropic vault, and start a session. ## Install [Section titled “Install”](#install) ```sh 1 pip install anthropic scalekit-sdk-python python-dotenv ``` ## Build [Section titled “Build”](#build) Run this once to create your Virtual MCP Server and Claude Managed Agent. Save the returned `mcp_id` and `agent_id` — you reuse them for every user and every session. builder.py ```python 1 import os 2 import anthropic 3 from scalekit import ScalekitClient 4 from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping 5 from dotenv import load_dotenv 6 7 load_dotenv() 8 9 anthropic_client = anthropic.Anthropic() 10 scalekit_client = ScalekitClient( 11 env_url=os.environ["SCALEKIT_ENV_URL"], 12 client_id=os.environ["SCALEKIT_CLIENT_ID"], 13 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 14 ) 15 16 GMAIL_TOOLS = ["gmail_fetch_mails"] 17 GCAL_TOOLS = [ 18 "googlecalendar_list_calendars", 19 "googlecalendar_list_events", 20 "googlecalendar_get_event_by_id", 21 "googlecalendar_create_event", 22 "googlecalendar_update_event", 23 ] 24 25 vmcp_response = scalekit_client.actions.mcp.create_config( 26 name="email-calendar-demo", 27 connection_tool_mappings=[ 28 McpConfigConnectionToolMapping( 29 connection_name="gmail", 30 tools=GMAIL_TOOLS, 31 ), 32 McpConfigConnectionToolMapping( 33 connection_name="googlecalendar", 34 tools=GCAL_TOOLS, 35 ), 36 ], 37 ) 38 39 mcp_id = vmcp_response.config.id 40 mcp_server_url = vmcp_response.config.mcp_server_url 41 42 agent = anthropic_client.beta.agents.create( 43 name="Email Meeting Manager", 44 model="claude-haiku-4-5-20251001", 45 system=( 46 "You are an email and calendar assistant. When invoked, you will:\n" 47 "1. Fetch the single most recent unread email from Gmail.\n" 48 "2. Summarize it in 2-3 sentences.\n" 49 "3. Create a Google Calendar event titled 'Action Required: ' " 50 "with your summary as the description." 51 ), 52 mcp_servers=[ 53 { 54 "type": "url", 55 "name": "email-calendar-mcp", 56 "url": mcp_server_url, 57 } 58 ], 59 tools=[ 60 {"type": "agent_toolset_20260401", "default_config": {"enabled": True}}, 61 { 62 "type": "mcp_toolset", 63 "mcp_server_name": "email-calendar-mcp", 64 "default_config": { 65 "enabled": True, 66 "permission_policy": {"type": "always_allow"}, 67 }, 68 }, 69 ], 70 ) 71 72 print("Virtual MCP ID:", mcp_id) 73 print("Agent ID: ", agent.id) ``` The agent definition references the `mcp_server_url` but carries no auth credentials. Authentication is injected at runtime via the Anthropic vault. ## Authorize user for external connections [Section titled “Authorize user for external connections”](#authorize-user-for-external-connections) Each user authorizes their Gmail and Google Calendar accounts once. All future agent sessions for that user reuse those connections. executor\_setup.py ```python 1 import os 2 from scalekit import ScalekitClient 3 from dotenv import load_dotenv 4 5 load_dotenv() 6 7 scalekit_client = ScalekitClient( 8 env_url=os.environ["SCALEKIT_ENV_URL"], 9 client_id=os.environ["SCALEKIT_CLIENT_ID"], 10 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 11 ) 12 13 # Retrieve mcp_id by listing Virtual MCP Servers filtered by name to use below 14 accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts( 15 config_id=mcp_id, 16 identifier=identifier, # your app's unique user ID 17 ) 18 19 for account in accounts_response.connected_accounts: 20 if account.connected_account_status != "ACTIVE": 21 auth_response = scalekit_client.actions.get_authorization_link( 22 identifier=identifier, 23 connection_name=account.connection_name, 24 ) 25 print(f"{account.connection_name} needs auth: {auth_response.link}") 26 else: 27 print(f"✓ {account.connection_name} — {account.connected_account_status}") ``` Surface the auth link in your app UI or send it via email. Users only need to do this once. ## Run a session [Section titled “Run a session”](#run-a-session) Run the following for each agent execution. 1. ## Check that connections are active [Section titled “Check that connections are active”](#check-that-connections-are-active) Before minting a token, confirm all connections are still `"ACTIVE"`. OAuth tokens for connected accounts can expire or be revoked. executor.py ```python 1 accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts( 2 config_id=mcp_id, 3 identifier=identifier, 4 ) 5 inactive = [ 6 a.connection_name 7 for a in accounts_response.connected_accounts 8 if a.connected_account_status != "ACTIVE" 9 ] 10 if inactive: 11 print("Inactive connections:", inactive) 12 # Prompt the user to re-authorize before proceeding ``` 2. ## Mint a session token and store in vault [Section titled “Mint a session token and store in vault”](#mint-a-session-token-and-store-in-vault) Mint a short-lived session token and store it in an Anthropic vault. Claude Managed Agents access the MCP server using the vault credential — not a direct bearer header. executor.py ```python 1 from datetime import timedelta 2 3 configs_response = scalekit_client.actions.mcp.list_configs(filter_id=mcp_id) 4 mcp_server_url = configs_response.configs[0].mcp_server_url 5 6 token_response = scalekit_client.actions.mcp.create_session_token( 7 mcp_config_id=mcp_id, 8 identifier=identifier, 9 expiry=timedelta(hours=1), 10 ) 11 token = token_response.token 12 13 # Create vault and credential on first run; update the token on subsequent runs 14 if vault_id and credential_id: 15 anthropic_client.beta.vaults.credentials.update( 16 credential_id, 17 vault_id=vault_id, 18 auth={"type": "static_bearer", "token": token}, 19 ) 20 else: 21 vault = anthropic_client.beta.vaults.create(display_name="email-calendar-vault") 22 vault_id = vault.id 23 credential = anthropic_client.beta.vaults.credentials.create( 24 vault_id, 25 display_name="email-calendar-credential", 26 auth={ 27 "type": "static_bearer", 28 "mcp_server_url": mcp_server_url, 29 "token": token, 30 }, 31 ) 32 credential_id = credential.id ``` 3. ## Start the session [Section titled “Start the session”](#start-the-session) Pass `vault_ids` to the session so the agent can authenticate against the MCP server. executor.py ```python 1 session = anthropic_client.beta.sessions.create( 2 agent=agent_id, 3 environment_id=os.environ["ANTHROPIC_ENVIRONMENT_ID"], 4 vault_ids=[vault_id], 5 ) 6 7 with anthropic_client.beta.sessions.events.stream(session_id=session.id) as stream: 8 anthropic_client.beta.sessions.events.send( 9 session_id=session.id, 10 events=[{"type": "user.message", "content": [{"type": "text", "text": prompt}]}], 11 ) 12 for event in stream: 13 if event.type == "agent.message": 14 for block in event.content: 15 if block.type == "text": 16 print(block.text, end="", flush=True) 17 elif event.type == "agent.mcp_tool_use": 18 print(f"\n→ {event.name}", flush=True) 19 elif event.type in ("session.status_idle", "session.status_terminated"): 20 break ``` --- # DOCUMENT BOUNDARY --- # CrewAI > Build a CrewAI agent with Scalekit-authenticated Gmail tools via MCP. CrewAI's MCPServerAdapter connects to a Scalekit MCP URL for automatic tool discovery. Build a CrewAI agent that reads a user’s Gmail inbox. Scalekit handles OAuth, token storage, and exposes tools over MCP. CrewAI’s `MCPServerAdapter` discovers the tools automatically — no manual schema conversion needed. [Full code on GitHub](https://github.com/scalekit-developers/crewai-scalekit-example) ## Install [Section titled “Install”](#install) ```sh 1 pip install crewai crewai-tools scalekit-sdk-python python-dotenv ``` ## Initialize [Section titled “Initialize”](#initialize) ```python 1 import os 2 from scalekit import ScalekitClient 3 from dotenv import find_dotenv, load_dotenv 4 5 load_dotenv(find_dotenv()) 6 7 scalekit_client = ScalekitClient( 8 env_url=os.environ["SCALEKIT_ENV_URL"], 9 client_id=os.environ["SCALEKIT_CLIENT_ID"], 10 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 11 ) 12 actions = scalekit_client.actions ``` ## Connect the user to Gmail [Section titled “Connect the user to Gmail”](#connect-the-user-to-gmail) ```python 1 response = actions.get_or_create_connected_account( 2 connection_name="gmail", 3 identifier="user_123", 4 ) 5 if response.connected_account.status != "ACTIVE": 6 link = actions.get_authorization_link(connection_name="gmail", identifier="user_123") 7 print("Authorize Gmail:", link.link) 8 input("Press Enter after authorizing...") ``` See [Authorize a user](/agentkit/tools/authorize/) for production auth handling. ## Build and run the agent [Section titled “Build and run the agent”](#build-and-run-the-agent) Get the Virtual MCP Server URL and mint a session token, then pass both to `MCPServerAdapter`. CrewAI discovers all available Gmail tools from the MCP server: ```python 1 from crewai import Agent, Crew, LLM, Task 2 from crewai_tools import MCPServerAdapter 3 from datetime import timedelta 4 5 # Retrieve config_id by listing Virtual MCP Servers filtered by name 6 list_response = actions.mcp.list_configs(filter_name="gmail-user-tools") 7 mcp_server_url = list_response.configs[0].mcp_server_url 8 mcp_id = list_response.configs[0].id 9 10 token_response = actions.mcp.create_session_token( 11 mcp_config_id=mcp_id, 12 identifier="user_123", 13 expiry=timedelta(hours=1), 14 ) 15 16 with MCPServerAdapter({ 17 "url": mcp_server_url, 18 "headers": {"Authorization": f"Bearer {token_response.token}"}, 19 "transport": "streamable-http", 20 }) as tools: 21 agent = Agent( 22 role="Email Assistant", 23 goal="Fetch and summarize the user's unread emails", 24 backstory="You are a helpful assistant with access to the user's Gmail inbox.", 25 tools=tools, 26 llm=LLM( 27 model=os.getenv("LLM_MODEL", "gpt-4o"), 28 base_url=os.getenv("OPENAI_BASE_URL"), 29 api_key=os.getenv("OPENAI_API_KEY"), 30 ), 31 verbose=True, 32 ) 33 34 task = Task( 35 description="Fetch the last 5 unread emails and provide a brief summary of each.", 36 expected_output="A list of 5 unread emails with subject, sender, and a one-sentence summary.", 37 agent=agent, 38 ) 39 40 result = Crew(agents=[agent], tasks=[task]).kickoff() 41 print(result) ``` ## Multi-agent crew [Section titled “Multi-agent crew”](#multi-agent-crew) CrewAI’s real strength is multi-agent orchestration. For a full example that splits email triage across three specialized agents (scanner, prioritizer, drafter), see the [CrewAI email triage cookbook](/cookbooks/crewai-agentkit-email-triage/). ## Get the MCP server URL [Section titled “Get the MCP server URL”](#get-the-mcp-server-url) The code above reads `mcp_server_url` from a Virtual MCP Server config. Create a config in the Scalekit Dashboard under **AgentKit → MCP Configs**. See [Virtual MCP Servers](/agentkit/mcp/overview/) for setup details. --- # DOCUMENT BOUNDARY --- # Google ADK > Build a Google ADK agent with Scalekit-authenticated Gmail tools. Scalekit returns native ADK tool objects; no schema reshaping needed. Build a Google ADK agent that reads a user’s Gmail inbox. Scalekit handles OAuth, token storage, and returns tools as native ADK tool objects compatible with any ADK agent. [Full code on GitHub](https://github.com/scalekit-inc/google-adk-agent-example) ## Install [Section titled “Install”](#install) ```sh 1 pip install scalekit-sdk-python google-adk ``` ## Initialize [Section titled “Initialize”](#initialize) ```python 1 import os 2 import asyncio 3 import scalekit.client 4 5 scalekit_client = scalekit.client.ScalekitClient( 6 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 7 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 8 env_url=os.getenv("SCALEKIT_ENV_URL"), 9 ) 10 actions = scalekit_client.actions ``` ## Connect the user to Gmail [Section titled “Connect the user to Gmail”](#connect-the-user-to-gmail) ```python 1 response = actions.get_or_create_connected_account( 2 connection_name="gmail", 3 identifier="user_123", 4 ) 5 if response.connected_account.status != "ACTIVE": 6 link = actions.get_authorization_link(connection_name="gmail", identifier="user_123") 7 print("Authorize Gmail:", link.link) 8 input("Press Enter after authorizing...") ``` See [Authorize a user](/agentkit/tools/authorize/) for production auth handling. ## Build and run the agent [Section titled “Build and run the agent”](#build-and-run-the-agent) `actions.google.get_tools()` returns native ADK tool objects. Pass them directly to a Google ADK `Agent`: ```python 1 from google.adk.agents import Agent 2 from google.adk.runners import Runner 3 from google.adk.sessions import InMemorySessionService 4 from google.genai import types 5 6 tools = actions.google.get_tools( 7 identifier="user_123", 8 connection_names=["gmail"], 9 page_size=100, # avoid missing tools when a connector has more than the default page 10 ) 11 12 agent = Agent( 13 name="gmail_assistant", 14 model="gemini-2.0-flash", 15 instruction="You are a helpful Gmail assistant.", 16 tools=tools, 17 ) 18 19 async def main(): 20 session_service = InMemorySessionService() 21 runner = Runner(agent=agent, app_name="gmail_app", session_service=session_service) 22 session = await session_service.create_session(app_name="gmail_app", user_id="user_123") 23 24 message = types.Content( 25 role="user", 26 parts=[types.Part(text="Fetch my last 5 unread emails and summarize them")], 27 ) 28 async for event in runner.run_async( 29 user_id="user_123", 30 session_id=session.id, 31 new_message=message, 32 ): 33 if event.is_final_response(): 34 print(event.response.text) 35 36 asyncio.run(main()) ``` ## Use MCP instead [Section titled “Use MCP instead”](#use-mcp-instead) Google ADK supports MCP via `MCPToolset`. Connect to a Scalekit-generated MCP URL to skip tool setup: ```python 1 from google.adk.agents import Agent 2 from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StreamableHTTPConnectionParams 3 4 agent = Agent( 5 name="gmail_assistant", 6 model="gemini-2.0-flash", 7 instruction="You are a helpful Gmail assistant.", 8 tools=[ 9 MCPToolset( 10 connection_params=StreamableHTTPConnectionParams(url=mcp_url) 11 ) 12 ], 13 ) ``` See [Virtual MCP Servers](/agentkit/mcp/overview/) to get `mcp_url`. --- # DOCUMENT BOUNDARY --- # LangChain > Build a LangChain agent with Scalekit-authenticated Gmail tools. Scalekit returns native LangChain tool objects; no schema reshaping needed. Build a LangChain agent that reads a user’s Gmail inbox. Scalekit handles OAuth, token storage, and returns tools in native LangChain format. Your agent code needs no Scalekit-specific logic beyond initialization. [Full code on GitHub](https://github.com/scalekit-inc/sample-langchain-agent) ## Install [Section titled “Install”](#install) ```sh 1 pip install scalekit-sdk-python langchain-openai ``` ## Initialize [Section titled “Initialize”](#initialize) ```python 1 import os 2 import scalekit.client 3 4 scalekit_client = scalekit.client.ScalekitClient( 5 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 6 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 ) 9 actions = scalekit_client.actions ``` ## Connect the user to Gmail [Section titled “Connect the user to Gmail”](#connect-the-user-to-gmail) ```python 1 response = actions.get_or_create_connected_account( 2 connection_name="gmail", 3 identifier="user_123", 4 ) 5 if response.connected_account.status != "ACTIVE": 6 link = actions.get_authorization_link(connection_name="gmail", identifier="user_123") 7 print("Authorize Gmail:", link.link) 8 input("Press Enter after authorizing...") ``` See [Authorize a user](/agentkit/tools/authorize/) for production auth handling. ## Build and run the agent [Section titled “Build and run the agent”](#build-and-run-the-agent) `actions.langchain.get_tools()` returns native `StructuredTool` objects. Bind them to your LLM and run the tool-calling loop: ```python 1 from langchain_openai import ChatOpenAI 2 from langchain_core.messages import HumanMessage, ToolMessage 3 4 tools = actions.langchain.get_tools( 5 identifier="user_123", 6 connection_names=["gmail"], 7 page_size=100, # avoid missing tools when a connector has more than the default page 8 ) 9 tool_map = {t.name: t for t in tools} 10 11 llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) 12 messages = [HumanMessage("Fetch my last 5 unread emails and summarize them")] 13 14 while True: 15 response = llm.invoke(messages) 16 messages.append(response) 17 if not response.tool_calls: 18 print(response.content) 19 break 20 for tc in response.tool_calls: 21 result = tool_map[tc["name"]].invoke(tc["args"]) 22 messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"])) ``` ## Use MCP instead [Section titled “Use MCP instead”](#use-mcp-instead) LangChain supports MCP via `langchain-mcp-adapters`. Install it, then connect to a Scalekit-generated MCP URL: ```sh 1 pip install langchain-mcp-adapters ``` ```python 1 import asyncio 2 from langchain_mcp_adapters.client import MultiServerMCPClient 3 from langchain_openai import ChatOpenAI 4 from langchain_core.messages import HumanMessage, ToolMessage 5 6 async def run(mcp_url: str): 7 async with MultiServerMCPClient( 8 {"scalekit": {"transport": "streamable_http", "url": mcp_url}} 9 ) as client: 10 tools = client.get_tools() 11 tool_map = {t.name: t for t in tools} 12 llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) 13 messages = [HumanMessage("Fetch my last 5 unread emails and summarize them")] 14 15 while True: 16 response = await llm.ainvoke(messages) 17 messages.append(response) 18 if not response.tool_calls: 19 print(response.content) 20 break 21 for tc in response.tool_calls: 22 result = await tool_map[tc["name"]].ainvoke(tc["args"]) 23 messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"])) 24 25 asyncio.run(run(mcp_url)) ``` See [Virtual MCP Servers](/agentkit/mcp/overview/) to get `mcp_url`. --- # DOCUMENT BOUNDARY --- # Mastra > Connect a Mastra agent to Scalekit tools using MCP. Mastra's MCP client connects to a Virtual MCP Server URL with a session token. Connect a Mastra agent to Scalekit tools using MCP. Mastra has native MCP support via `@mastra/mcp`. Pass a Scalekit Virtual MCP Server URL and a session token, and Mastra handles tool discovery automatically. ## Install [Section titled “Install”](#install) ```sh 1 npm install @scalekit-sdk/node @mastra/core @mastra/mcp @ai-sdk/openai ``` ## Create the Virtual MCP server [Section titled “Create the Virtual MCP server”](#create-the-virtual-mcp-server) Create the server once per agent role, not once per user. The response includes a static `mcp_server_url` that every user and every session reuses. ```python 1 # Backend (Python): run once, then save the values 2 from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping 3 4 vmcp_response = scalekit_client.actions.mcp.create_config( 5 name="gmail-user-tools", 6 connection_tool_mappings=[ 7 McpConfigConnectionToolMapping( 8 connection_name="gmail", 9 tools=["gmail_fetch_mails"], 10 ), 11 ], 12 ) 13 14 config_id = vmcp_response.config.id 15 mcp_server_url = vmcp_response.config.mcp_server_url ``` See [Set up and connect a Virtual MCP server](/agentkit/mcp/configure-mcp-server/) for the full setup, including how to choose which tools to expose. ## Mint a session token for the user [Section titled “Mint a session token for the user”](#mint-a-session-token-for-the-user) The server URL is static. The **session token** carries the user identity. Mint a fresh token before each agent run and pass it to your Mastra app. ```python 1 # Backend (Python): run before each agent session 2 from datetime import timedelta 3 4 from scalekit.common.exceptions import ( 5 ScalekitNotFoundException, 6 ScalekitUnauthorizedException, 7 ScalekitServerException, 8 ) 9 10 try: 11 list_response = scalekit_client.actions.mcp.list_configs(filter_name="gmail-user-tools") 12 mcp_server_url = list_response.configs[0].mcp_server_url 13 config_id = list_response.configs[0].id 14 15 token_response = scalekit_client.actions.mcp.create_session_token( 16 mcp_config_id=config_id, 17 identifier="user_123", 18 expiry=timedelta(hours=1), 19 ) 20 # Return mcp_server_url and token_response.token to the Mastra app for this user only 21 except ScalekitNotFoundException: 22 # The server was deleted or renamed — recreate it, then retry 23 raise 24 except ScalekitUnauthorizedException: 25 # Scalekit client credentials are wrong or expired — fix the environment variables 26 raise 27 except ScalekitServerException as e: 28 # Unexpected platform error — do not start the agent without a token 29 print(e.error_code, e.http_status) 30 raise ``` Do not start the agent when minting fails. An agent that runs without a token calls every tool and gets a `401`. See [Error handling](/agentkit/sdks/python/errors/) for the full exception list. Set `expiry` longer than the expected agent run. `create_session_token` also mints replacements. Call it again whenever you need a new token. Do not share one session token across users The `mcp_server_url` is safe to share, because every user gets the same URL. The session token is different. Each token is scoped to one identifier, and any request carrying that token runs as that user. Mint a token per user on the server, and never put a token in client-side code. ## Build the agent [Section titled “Build the agent”](#build-the-agent) Pass the static server URL to `MCPClient`, and the user’s session token as a bearer header in `requestInit`. Mastra fetches the tool list and schemas automatically: ```typescript 1 import { Agent } from '@mastra/core/agent'; 2 import { MCPClient } from '@mastra/mcp'; 3 import { openai } from '@ai-sdk/openai'; 4 5 // From your backend for the authenticated user — not a shared process-wide secret 6 const { mcpServerUrl, mcpToken } = await getMcpSessionForUser(currentUserId); 7 8 const mcp = new MCPClient({ 9 servers: { 10 scalekit: { 11 url: new URL(mcpServerUrl), 12 requestInit: { 13 headers: { Authorization: `Bearer ${mcpToken}` }, 14 }, 15 }, 16 }, 17 }); 18 19 const tools = await mcp.getTools(); 20 21 const agent = new Agent({ 22 name: 'gmail_assistant', 23 instructions: 'You are a helpful Gmail assistant.', 24 model: openai('gpt-4o'), 25 tools, 26 }); 27 28 const result = await agent.generate('Fetch my last 5 unread emails and summarize them'); 29 console.log(result.text); 30 31 await mcp.disconnect(); ``` --- # DOCUMENT BOUNDARY --- # OpenAI > Build an OpenAI agent with Scalekit-authenticated tools. Convert Scalekit's tool schemas to OpenAI's function calling format in one step. Build an agent using OpenAI’s GPT models that reads a user’s Gmail inbox. Scalekit’s tool schemas use `input_schema`: rename it to `parameters` and wrap it in OpenAI’s function format. ## Install [Section titled “Install”](#install) * Python ```sh 1 pip install scalekit-sdk-python openai ``` * Node.js ```sh 1 npm install @scalekit-sdk/node openai ``` ## Initialize [Section titled “Initialize”](#initialize) * Python ```python 1 import os, json 2 import scalekit.client 3 from openai import OpenAI 4 from google.protobuf.json_format import MessageToDict 5 6 scalekit_client = scalekit.client.ScalekitClient( 7 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 8 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 9 env_url=os.getenv("SCALEKIT_ENV_URL"), 10 ) 11 actions = scalekit_client.actions 12 client = OpenAI() ``` * Node.js ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; 3 import OpenAI from 'openai'; 4 5 const scalekit = new ScalekitClient( 6 process.env.SCALEKIT_ENV_URL!, 7 process.env.SCALEKIT_CLIENT_ID!, 8 process.env.SCALEKIT_CLIENT_SECRET!, 9 ); 10 const openai = new OpenAI(); ``` ## Connect the user to Gmail [Section titled “Connect the user to Gmail”](#connect-the-user-to-gmail) * Python ```python 1 response = actions.get_or_create_connected_account( 2 connection_name="gmail", 3 identifier="user_123", 4 ) 5 if response.connected_account.status != "ACTIVE": 6 link = actions.get_authorization_link(connection_name="gmail", identifier="user_123") 7 print("Authorize Gmail:", link.link) 8 input("Press Enter after authorizing...") ``` * Node.js ```typescript 1 const { connectedAccount } = await scalekit.actions.getOrCreateConnectedAccount({ 2 connectionName: 'gmail', 3 identifier: 'user_123', 4 }); 5 if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { 6 const { link } = await scalekit.actions.getAuthorizationLink({ connectionName: 'gmail', identifier: 'user_123' }); 7 console.log('Authorize Gmail:', link); 8 } ``` See [Authorize a user](/agentkit/tools/authorize/) for production auth handling. ## Run the agent [Section titled “Run the agent”](#run-the-agent) Fetch tools scoped to this user, convert to OpenAI’s function format, then run the tool-calling loop: * Python ```python 1 # Fetch and convert tools to OpenAI format 2 scoped_response, _ = actions.tools.list_scoped_tools( 3 identifier="user_123", 4 filter={"connection_names": ["gmail"]}, 5 page_size=100, # fetch beyond the default page so no connector tools are missed 6 ) 7 llm_tools = [ 8 { 9 "type": "function", 10 "function": { 11 "name": MessageToDict(t.tool).get("definition", {}).get("name"), 12 "description": MessageToDict(t.tool).get("definition", {}).get("description", ""), 13 "parameters": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}), 14 }, 15 } 16 for t in scoped_response.tools 17 ] 18 19 # Run the agent loop 20 messages = [{"role": "user", "content": "Fetch my last 5 unread emails and summarize them"}] 21 22 while True: 23 response = client.chat.completions.create( 24 model="gpt-4o", 25 tools=llm_tools, 26 messages=messages, 27 ) 28 message = response.choices[0].message 29 if not message.tool_calls: 30 print(message.content) 31 break 32 33 messages.append(message) 34 for tc in message.tool_calls: 35 result = actions.execute_tool( 36 tool_name=tc.function.name, 37 identifier="user_123", 38 tool_input=json.loads(tc.function.arguments), 39 ) 40 messages.append({ 41 "role": "tool", 42 "tool_call_id": tc.id, 43 "content": str(result.data), 44 }) ``` * Node.js ```typescript 1 // Fetch and convert tools to OpenAI format 2 const { tools } = await scalekit.tools.listScopedTools('user_123', { 3 filter: { connectionNames: ['gmail'] }, 4 pageSize: 100, // fetch beyond the default page so no connector tools are missed 5 }); 6 const llmTools: OpenAI.ChatCompletionTool[] = tools.map(t => ({ 7 type: 'function', 8 function: { 9 name: t.tool.definition.name, 10 description: t.tool.definition.description, 11 parameters: t.tool.definition.input_schema, 12 }, 13 })); 14 15 // Run the agent loop 16 const messages: OpenAI.ChatCompletionMessageParam[] = [ 17 { role: 'user', content: 'Fetch my last 5 unread emails and summarize them' }, 18 ]; 19 20 while (true) { 21 const response = await openai.chat.completions.create({ 22 model: 'gpt-4o', 23 tools: llmTools, 24 messages, 25 }); 26 const message = response.choices[0].message; 27 if (!message.tool_calls?.length) { 28 console.log(message.content); 29 break; 30 } 31 messages.push(message); 32 for (const tc of message.tool_calls) { 33 const result = await scalekit.actions.executeTool({ 34 toolName: tc.function.name, 35 identifier: 'user_123', 36 toolInput: JSON.parse(tc.function.arguments), 37 }); 38 messages.push({ role: 'tool', tool_call_id: tc.id, content: JSON.stringify(result.data) }); 39 } 40 } ``` ## Use the Responses API [Section titled “Use the Responses API”](#use-the-responses-api) OpenAI’s [Responses API](https://platform.openai.com/docs/api-reference/responses) is a stateful alternative to Chat Completions. Instead of managing conversation history yourself, you pass `previous_response_id` to continue a session. The tool schema format is the same. * Python ```python 1 response = client.responses.create( 2 model="gpt-4o", 3 input="Fetch my last 5 unread emails and summarize them", 4 tools=llm_tools, 5 ) 6 7 while any(item.type == "function_call" for item in response.output): 8 tool_results = [ 9 { 10 "type": "function_call_output", 11 "call_id": item.call_id, 12 "output": str(actions.execute_tool( 13 tool_name=item.name, 14 identifier="user_123", 15 tool_input=json.loads(item.arguments), 16 ).data), 17 } 18 for item in response.output 19 if item.type == "function_call" 20 ] 21 response = client.responses.create( 22 model="gpt-4o", 23 previous_response_id=response.id, 24 input=tool_results, 25 tools=llm_tools, 26 ) 27 28 for item in response.output: 29 if item.type == "message": 30 print(item.content[0].text) ``` * Node.js ```typescript 1 let response = await openai.responses.create({ 2 model: 'gpt-4o', 3 input: 'Fetch my last 5 unread emails and summarize them', 4 tools: llmTools, 5 }); 6 7 while (response.output.some(item => item.type === 'function_call')) { 8 const toolResults = await Promise.all( 9 response.output 10 .filter(item => item.type === 'function_call') 11 .map(async item => { 12 const result = await scalekit.actions.executeTool({ 13 toolName: item.name, 14 identifier: 'user_123', 15 toolInput: JSON.parse(item.arguments), 16 }); 17 return { 18 type: 'function_call_output' as const, 19 call_id: item.call_id, 20 output: JSON.stringify(result.data), 21 }; 22 }) 23 ); 24 response = await openai.responses.create({ 25 model: 'gpt-4o', 26 previous_response_id: response.id, 27 input: toolResults, 28 tools: llmTools, 29 }); 30 } 31 32 const message = response.output.find(item => item.type === 'message'); 33 if (message?.type === 'message') console.log(message.content[0].text); ``` ## Use MCP instead [Section titled “Use MCP instead”](#use-mcp-instead) If you prefer the MCP approach, connect your OpenAI agent via the [Vercel AI SDK + MCP](/agentkit/examples/vercel-ai#use-mcp-instead) or LangChain’s MCP client with a Scalekit-generated URL. See [Virtual MCP Servers](/agentkit/mcp/overview/) for the URL setup. --- # DOCUMENT BOUNDARY --- # Vercel AI SDK > Build a Vercel AI SDK agent with Scalekit-authenticated tools using the tool() helper and jsonSchema() adapter. Build an agent using the Vercel AI SDK that reads a user’s Gmail inbox. Use `tool()` and `jsonSchema()` from the `ai` package to wrap Scalekit tools. No manual schema conversion needed. ## Install [Section titled “Install”](#install) ```sh 1 npm install @scalekit-sdk/node ai @ai-sdk/openai ``` ## Initialize [Section titled “Initialize”](#initialize) ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET!, 8 ); ``` ## Connect the user to Gmail [Section titled “Connect the user to Gmail”](#connect-the-user-to-gmail) ```typescript 1 const { connectedAccount } = await scalekit.actions.getOrCreateConnectedAccount({ 2 connectionName: 'gmail', 3 identifier: 'user_123', 4 }); 5 if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { 6 const { link } = await scalekit.actions.getAuthorizationLink({ connectionName: 'gmail', identifier: 'user_123' }); 7 console.log('Authorize Gmail:', link); 8 } ``` See [Authorize a user](/agentkit/tools/authorize/) for production auth handling. ## Run the agent [Section titled “Run the agent”](#run-the-agent) ```typescript 1 import { generateText, jsonSchema, stepCountIs, tool } from 'ai'; 2 import { openai } from '@ai-sdk/openai'; 3 4 const { tools: scopedTools } = await scalekit.tools.listScopedTools('user_123', { 5 filter: { connectionNames: ['gmail'] }, 6 pageSize: 100, // fetch beyond the default page so no connector tools are missed 7 }); 8 9 const tools = Object.fromEntries( 10 scopedTools.map(t => [ 11 t.tool.definition.name, 12 tool({ 13 description: t.tool.definition.description, 14 parameters: jsonSchema(t.tool.definition.input_schema ?? { type: 'object', properties: {} }), 15 execute: async (args) => { 16 const result = await scalekit.actions.executeTool({ 17 toolName: t.tool.definition.name, 18 identifier: 'user_123', 19 toolInput: args, 20 }); 21 return result.data; 22 }, 23 }), 24 ]), 25 ); 26 27 const { text } = await generateText({ 28 model: openai('gpt-4o'), 29 tools, 30 stopWhen: stepCountIs(5), 31 prompt: 'Fetch my last 5 unread emails and summarize them', 32 }); 33 console.log(text); ``` ## Use MCP instead [Section titled “Use MCP instead”](#use-mcp-instead) The Vercel AI SDK supports MCP via `experimental_createMCPClient`. Pass the Virtual MCP Server URL and a session token to connect without any tool schema setup: ```typescript 1 import { experimental_createMCPClient, generateText } from 'ai'; 2 import { openai } from '@ai-sdk/openai'; 3 4 const mcpClient = await experimental_createMCPClient({ 5 transport: { 6 type: 'streamable-http', 7 url: mcpUrl, // mcp_server_url from Virtual MCP Server config 8 headers: { Authorization: `Bearer ${mcpToken}` }, 9 }, 10 }); 11 12 const tools = await mcpClient.tools(); 13 14 const { text } = await generateText({ 15 model: openai('gpt-4o'), 16 tools, 17 stopWhen: stepCountIs(5), 18 prompt: 'Fetch my last 5 unread emails and summarize them', 19 }); 20 await mcpClient.close(); 21 console.log(text); ``` See [Virtual MCP Servers](/agentkit/mcp/overview/) for setup details and how to get `mcpUrl` and `mcpToken`. --- # DOCUMENT BOUNDARY --- # Add Enterprise SSO to Next.js with Auth.js > Wire Scalekit's OIDC interface into Auth.js to ship per-tenant enterprise SSO in Next.js without touching SAML or IdP-specific code. Enterprise customers don’t want to hand over their employees’ credentials to your app — they want SSO through their own IdP. Auth.js handles sessions well, but it has no concept of per-tenant SAML connections or routing by organization. Scalekit fills that gap: it exposes a single OIDC-compliant endpoint that sits in front of every IdP your customers use. This cookbook wires those two pieces together so your app gets enterprise SSO without writing a line of SAML code. ## The problem [Section titled “The problem”](#the-problem) Adding enterprise SSO to a Next.js app sounds simple until you start building it: * **SAML complexity** — every IdP (Okta, Azure AD, Google Workspace, Ping) uses different metadata, certificate rotation schedules, and attribute mappings. You end up maintaining per-IdP configuration forever. * **Per-tenant routing** — each sign-in attempt needs to resolve to the right connection for that customer. A single `clientId` in Auth.js doesn’t model this. * **Duplicate boilerplate** — Okta setup is not Azure AD setup. You write the integration N times, once per IdP your enterprise customers use. * **Session ownership** — SAML assertions and OIDC tokens are not app sessions. Bridging them correctly (handling expiry, attribute claims, refresh) is error-prone without a clear seam. ## Who needs this [Section titled “Who needs this”](#who-needs-this) This cookbook is for you if: * ✅ You’re building a multi-tenant B2B SaaS app * ✅ You already use Auth.js for session management and want to keep it * ✅ You have enterprise customers who require SSO through their own IdP * ✅ You want to avoid ripping out Auth.js to adopt a fully managed auth platform You **don’t** need this if: * ❌ You’re building a consumer app with no enterprise requirements * ❌ Your app has no concept of organizations or tenants * ❌ You don’t have customers asking for Okta/Azure AD/Google Workspace integration ## The solution [Section titled “The solution”](#the-solution) Scalekit exposes a single OIDC-compliant authorization endpoint. Auth.js treats it like any other OIDC provider and manages the session after the callback. You never write SAML code — Scalekit handles the protocol translation, certificate rotation, and attribute normalization for every IdP your customers connect. The routing params (`connection_id`, `organization_id`, `domain`) let you target the right enterprise connection at sign-in time. ## Implementation [Section titled “Implementation”](#implementation) ### 1. Set up Scalekit [Section titled “1. Set up Scalekit”](#1-set-up-scalekit) Create an environment in the [Scalekit dashboard](https://app.scalekit.com/): 1. Copy your **Issuer URL** (e.g. `https://yourenv.scalekit.dev`), **Client ID** (`skc_...`), and **Client Secret** from **API Keys**. 2. Register your redirect URI: `http://localhost:3000/auth/callback/scalekit` > This guide sets `basePath: "/auth"` in `auth.ts` — a custom override. The Auth.js v5 default is `/api/auth`. Register your redirect URI to match whatever `basePath` you configure or the OAuth flow will fail. 3. Create an **Organization** and add an **SSO Connection** for your test IdP. 4. Copy the **Connection ID** (`conn_...`) — you’ll use it to route sign-in attempts during development. ### 2. Install dependencies [Section titled “2. Install dependencies”](#2-install-dependencies) ```bash 1 pnpm add next-auth ``` Auth.js v5 (`next-auth@5`) ships as a single package. No separate adapter is needed for JWT sessions. ### 3. Add the Scalekit provider [Section titled “3. Add the Scalekit provider”](#3-add-the-scalekit-provider) providers/scalekit.ts ```typescript 1 import type { OAuthConfig, OAuthUserConfig } from "next-auth/providers" 2 3 export interface ScalekitProfile extends Record { 4 sub: string 5 email: string 6 email_verified: boolean 7 name: string 8 given_name: string 9 family_name: string 10 picture: string 11 oid: string // organization_id 12 } 13 14 export default function Scalekit

( 15 options: OAuthUserConfig

& { 16 issuer: string 17 organizationId?: string 18 connectionId?: string 19 domain?: string 20 } 21 ): OAuthConfig

{ 22 const { issuer, organizationId, connectionId, domain } = options 23 24 return { 25 id: "scalekit", 26 name: "Scalekit", 27 type: "oidc", 28 issuer, 29 authorization: { 30 params: { 31 scope: "openid email profile", 32 ...(connectionId && { connection_id: connectionId }), 33 ...(organizationId && { organization_id: organizationId }), 34 ...(domain && { domain }), 35 }, 36 }, 37 profile(profile) { 38 return { 39 id: profile.sub, 40 name: profile.name ?? `${profile.given_name} ${profile.family_name}`, 41 email: profile.email, 42 image: profile.picture ?? null, 43 } 44 }, 45 style: { bg: "#6f42c1", text: "#fff" }, 46 options, 47 } 48 } ``` After PR #13392 merges, replace the local import with: ```typescript 1 import Scalekit from "next-auth/providers/scalekit" ``` ### 4. Configure `auth.ts` [Section titled “4. Configure auth.ts”](#4-configure-authts) Create `auth.ts` in your project root: ```typescript 1 import NextAuth from "next-auth" 2 import Scalekit from "./providers/scalekit" // → "next-auth/providers/scalekit" after PR #13392 3 4 export const { handlers, auth, signIn, signOut } = NextAuth({ 5 providers: [ 6 Scalekit({ 7 issuer: process.env.AUTH_SCALEKIT_ISSUER!, 8 clientId: process.env.AUTH_SCALEKIT_ID!, 9 clientSecret: process.env.AUTH_SCALEKIT_SECRET!, 10 // Routing: set one of these (see step 7 for strategy) 11 connectionId: process.env.AUTH_SCALEKIT_CONNECTION_ID, 12 }), 13 ], 14 basePath: "/auth", 15 session: { strategy: "jwt" }, 16 }) ``` `basePath: "/auth"` is required to match the redirect URI you registered in step 1. Without it, Auth.js uses `/api/auth` and the Scalekit callback will fail. ### 5. Set environment variables [Section titled “5. Set environment variables”](#5-set-environment-variables) .env.local ```bash 1 # Generate with: npx auth secret 2 AUTH_SECRET= 3 4 # From Scalekit dashboard → API Keys 5 AUTH_SCALEKIT_ISSUER=https://yourenv.scalekit.dev 6 AUTH_SCALEKIT_ID=skc_... 7 AUTH_SCALEKIT_SECRET= 8 9 # Connection ID for development routing (conn_...) 10 # In production, resolve this dynamically per tenant — see step 7 11 AUTH_SCALEKIT_CONNECTION_ID=conn_... ``` `AUTH_SECRET` is not optional. Auth.js uses it to sign JWTs and encrypt session cookies. Missing it causes sign-in to fail silently. ### 6. Wire up route handlers [Section titled “6. Wire up route handlers”](#6-wire-up-route-handlers) Create `app/auth/[...nextauth]/route.ts`: ```typescript 1 import { handlers } from "@/auth" 2 export const { GET, POST } = handlers ``` This exposes `GET /auth/callback/scalekit` and `POST /auth/signout` — the endpoints Auth.js needs. The directory must be `app/auth/` (not `app/api/auth/`) to match the `basePath` you configured. ### 7. SSO routing strategies [Section titled “7. SSO routing strategies”](#7-sso-routing-strategies) Scalekit resolves which IdP connection to activate using these params (highest to lowest precedence): ```typescript 1 Scalekit({ 2 issuer: process.env.AUTH_SCALEKIT_ISSUER!, 3 clientId: process.env.AUTH_SCALEKIT_ID!, 4 clientSecret: process.env.AUTH_SCALEKIT_SECRET!, 5 6 // Option A — exact connection (dev / single-tenant use) 7 connectionId: "conn_...", 8 9 // Option B — org's active connection (multi-tenant: look up org from user's DB record) 10 organizationId: "org_...", 11 12 // Option C — resolve org from email domain (useful at login prompt) 13 domain: "acme.com", 14 }) ``` In production, don’t hardcode these values. Store `organizationId` or `connectionId` per tenant in your database, then construct the `signIn()` call dynamically based on the authenticated user’s org: ```typescript 1 // Example: look up org at sign-in time 2 const org = await db.organizations.findByDomain(emailDomain) 3 4 await signIn("scalekit", { 5 organizationId: org.scalekitOrgId, 6 redirectTo: "/dashboard", 7 }) ``` ### 8. Trigger sign-in and read the session [Section titled “8. Trigger sign-in and read the session”](#8-trigger-sign-in-and-read-the-session) A server component reads the session, and a sign-in form triggers the flow: app/page.tsx ```typescript 1 import { auth, signIn } from "@/auth" 2 3 export default async function Home() { 4 const session = await auth() 5 6 if (session) { 7 return ( 8

9

Signed in as {session.user?.email}

10
11 ) 12 } 13 14 return ( 15
{ 17 "use server" 18 await signIn("scalekit", { redirectTo: "/dashboard" }) 19 }} 20 > 21 22
23 ) 24 } ``` `session.user` includes `name`, `email`, and `image` normalized from the Scalekit OIDC profile. ## Testing [Section titled “Testing”](#testing) 1. Run `pnpm dev` and visit `http://localhost:3000`. 2. Click **Sign in with SSO** — you should be redirected to your IdP’s login page. 3. Complete authentication and confirm you land back on your app. 4. Check the session at `http://localhost:3000/api/auth/session` or read it from a server component — you should see `user.email` populated. If the redirect fails immediately, enable debug logging to trace the OIDC callback: ```bash 1 AUTH_DEBUG=true pnpm dev ``` ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) 1. **Wrong redirect URI** — registering `/api/auth/callback/scalekit` instead of `/auth/callback/scalekit`. This guide sets `basePath: "/auth"` (a custom override, not the v5 default — the default remains `/api/auth`). The URI in Scalekit’s dashboard must match the callback path Auth.js actually uses. 2. **Missing `AUTH_SECRET`** — sign-in appears to start but fails on the callback with no visible error. Always set `AUTH_SECRET`. Generate one with `npx auth secret`. 3. **Hardcoding `connectionId` in production** — works in development, breaks for every other tenant. Store connection identifiers per-organization in your database and resolve them at runtime. 4. **Missing `basePath` in `auth.ts`** — if you omit `basePath: "/auth"`, Auth.js defaults to `/api/auth`. Your route handler must be at `app/api/auth/[...nextauth]/route.ts` and your redirect URI must use `/api/auth/callback/scalekit`. Pick one and be consistent. 5. **Using the wrong import path** — `next-auth/providers/scalekit` only resolves after PR #13392 merges. Until then, the local file at `./providers/scalekit` is the correct import. ## Production notes [Section titled “Production notes”](#production-notes) * **Rotate secrets without code changes** — update `AUTH_SCALEKIT_SECRET` in your environment configuration; Scalekit handles IdP certificate rotation automatically. * **Dynamic connection routing** — store `organizationId` or `connectionId` per tenant in your database. Resolve at sign-in time based on the user’s email domain or their existing tenant membership. * **Debug OIDC callback issues** — set `AUTH_DEBUG=true` temporarily in production to emit detailed callback traces. Remove it after diagnosing. * **Session persistence** — JWT sessions (the default) work without a database. If you need server-side session invalidation, add an Auth.js adapter (e.g. Prisma, Drizzle) and switch to `strategy: "database"`. * **Scalekit handles IdP complexity** — certificate rotation, SAML metadata updates, and attribute mapping changes happen in the Scalekit dashboard without touching your code. ## Next steps [Section titled “Next steps”](#next-steps) * [scalekit-developers/scalekit-authjs-example](https://github.com/scalekit-developers/scalekit-authjs-example) — full working repo for this cookbook * [Auth.js PR #13392](https://github.com/nextauthjs/next-auth/pull/13392) — track native Scalekit provider availability * [Scalekit SSO routing documentation](https://docs.scalekit.com/sso/quickstart) — full reference for `connection_id`, `organization_id`, and `domain` routing params * [Auth.js adapters](https://authjs.dev/getting-started/database) — add database-backed sessions for server-side invalidation * [Scalekit organization management API](https://docs.scalekit.com/apis) — look up `organizationId` dynamically from your tenant records --- # DOCUMENT BOUNDARY --- # Add Scalekit hosted auth to a Next.js app > Wire Scalekit hosted login into the Next.js App Router with server-side sessions, transparent token refresh, and logout. Scalekit’s [Full Stack Auth journey](/authenticate/fsa/quickstart/) shows the hosted-login flow with Express, Flask, Gin, and Spring. None of those map cleanly onto the Next.js App Router, where there is no long-lived `req`/`res` pair: authentication runs across Route Handlers, Server Components, and middleware, and sessions live in cookies you set from the server. This cookbook ports the complete flow to Next.js 15 (App Router): redirect users to Scalekit’s hosted login, exchange the authorization code on a callback Route Handler, store tokens in `HttpOnly` cookies, validate and refresh them on every request, and sign users out cleanly. You get enterprise SSO, social login, and passwordless out of the box, because the hosted page handles every method you enable in the dashboard. ## The problem [Section titled “The problem”](#the-problem) You want production-grade authentication in a Next.js App Router app, and you have decided to use Scalekit’s hosted login page so you don’t build or maintain login UI. Three things make this non-trivial: * **No `req`/`res` lifecycle.** The Express examples set cookies on a response object. In the App Router you set cookies through the `cookies()` API and `NextResponse`, in different files for different stages of the flow. * **The Edge runtime can’t run the Node SDK.** Middleware runs on the Edge runtime by default. The Scalekit Node SDK depends on Node APIs, so token validation belongs in the Node.js runtime, not in default middleware. * **Refresh tokens rotate.** Scalekit issues a new refresh token every time you redeem one. If you store tokens carelessly, a refresh races itself and logs the user out. ## The approach [Section titled “The approach”](#the-approach) Keep every token operation on the server and give each stage of the flow its own file: | Stage | File | Runtime | | ------------------------------------ | --------------------------------- | ------- | | Build the Scalekit client once | `lib/scalekit.ts` | Node.js | | Read and write session cookies | `lib/session.ts` | Node.js | | Start login (redirect to Scalekit) | `app/login/route.ts` | Node.js | | Handle the callback (code exchange) | `app/api/callback/route.ts` | Node.js | | Validate and refresh on each request | `lib/session.ts` → `getSession()` | Node.js | | Sign out | `app/logout/route.ts` | Node.js | Validate the session inside Server Components and Route Handlers — both run on the Node.js runtime — instead of inside Edge middleware. Use middleware only as a lightweight gate that checks for the presence of a session cookie. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A Next.js 15 app using the App Router. * A Scalekit account with an **Environment URL**, **Client ID**, and **Client Secret** from **Dashboard > Developers > API Credentials**. * `http://localhost:3000/api/callback` registered under **Dashboard > Authentication > Redirects > Allowed callback URLs**, and `http://localhost:3000/login` registered as a **Post logout URL**. Install the SDK: Terminal ```bash pnpm add @scalekit-sdk/node ``` Add your credentials to `.env.local`: .env.local ```bash SCALEKIT_ENV_URL="https://your-subdomain.scalekit.com" SCALEKIT_CLIENT_ID="skc_..." SCALEKIT_CLIENT_SECRET="..." # Never expose this to the browser. Server-only. SESSION_COOKIE_SECRET="a-32-byte-random-string-for-cookie-encryption" ``` ## Create the Scalekit client [Section titled “Create the Scalekit client”](#create-the-scalekit-client) Instantiate the client once and reuse it. Reading credentials from the environment keeps the secret out of your bundle, and a module-level singleton avoids reconnecting on every request. lib/scalekit.ts ```ts 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 // Security: credentials come from server-only env vars. The client secret must 4 // never reach the browser, so this module is only ever imported in server code. 5 export const scalekit = new Scalekit( 6 process.env.SCALEKIT_ENV_URL!, 7 process.env.SCALEKIT_CLIENT_ID!, 8 process.env.SCALEKIT_CLIENT_SECRET!, 9 ); 10 11 export const REDIRECT_URI = 'http://localhost:3000/api/callback'; ``` ## Start the login flow [Section titled “Start the login flow”](#start-the-login-flow) Generate a `state` value, store it in a short-lived cookie to defend against CSRF, and redirect the browser to Scalekit’s hosted login page. Include `offline_access` in the scopes so Scalekit returns a refresh token. app/login/route.ts ```ts 1 import { randomBytes } from 'node:crypto'; 2 import { cookies } from 'next/headers'; 3 import { redirect } from 'next/navigation'; 4 import { scalekit, REDIRECT_URI } from '@/lib/scalekit'; 5 6 export async function GET() { 7 // Security: a random state ties the callback back to this browser. Without it, 8 // an attacker could replay a callback and complete login as someone else (CSRF). 9 const state = randomBytes(32).toString('hex'); 10 11 const cookieStore = await cookies(); 12 cookieStore.set('sk_oauth_state', state, { 13 httpOnly: true, // Block JavaScript access to mitigate XSS token theft. 14 secure: process.env.NODE_ENV === 'production', // HTTPS-only outside local dev. 15 sameSite: 'lax', 16 maxAge: 60 * 10, // The state is only needed for the next 10 minutes. 17 path: '/', 18 }); 19 20 const authorizationUrl = scalekit.getAuthorizationUrl(REDIRECT_URI, { 21 scopes: ['openid', 'profile', 'email', 'offline_access'], 22 state, 23 }); 24 25 redirect(authorizationUrl); 26 } ``` ## Handle the callback [Section titled “Handle the callback”](#handle-the-callback) After the user authenticates, Scalekit redirects back with a `code` and your `state`. Validate the `state`, exchange the code for tokens with `authenticateWithCode`, then store the tokens in `HttpOnly` cookies. app/api/callback/route.ts ```ts 1 import { cookies } from 'next/headers'; 2 import { NextRequest, NextResponse } from 'next/server'; 3 import { scalekit, REDIRECT_URI } from '@/lib/scalekit'; 4 import { setSessionCookies } from '@/lib/session'; 5 6 export async function GET(request: NextRequest) { 7 const { searchParams } = request.nextUrl; 8 const code = searchParams.get('code'); 9 const state = searchParams.get('state'); 10 const error = searchParams.get('error'); 11 12 const cookieStore = await cookies(); 13 const storedState = cookieStore.get('sk_oauth_state')?.value; 14 cookieStore.delete('sk_oauth_state'); // Use the state only once. 15 16 if (error) { 17 return NextResponse.redirect(new URL('/login?error=auth_failed', request.url)); 18 } 19 20 // Security: reject the callback unless the returned state matches the one we 21 // issued. A mismatch means the response did not originate from our redirect. 22 if (!code || !state || state !== storedState) { 23 return NextResponse.redirect(new URL('/login?error=invalid_state', request.url)); 24 } 25 26 try { 27 const { user, idToken, accessToken, refreshToken } = 28 await scalekit.authenticateWithCode(code, REDIRECT_URI); 29 30 const response = NextResponse.redirect(new URL('/dashboard', request.url)); 31 setSessionCookies(response, { idToken, accessToken, refreshToken }); 32 return response; 33 } catch { 34 return NextResponse.redirect(new URL('/login?error=exchange_failed', request.url)); 35 } 36 } ``` A refresh token requires offline\_access Scalekit only returns `refreshToken` when the authorization request includes the `offline_access` scope. If you omit it, sessions end as soon as the access token expires because there is nothing to refresh. ## Store and read the session [Section titled “Store and read the session”](#store-and-read-the-session) Centralize cookie handling so login, refresh, and logout stay consistent. Keep tokens in `HttpOnly`, `Secure` cookies, and scope the refresh token to a narrow path so it is sent only when you need it. lib/session.ts ```ts 1 import { cookies } from 'next/headers'; 2 import type { NextResponse } from 'next/server'; 3 import { scalekit } from '@/lib/scalekit'; 4 5 type Tokens = { idToken: string; accessToken: string; refreshToken: string }; 6 7 const COOKIE_BASE = { 8 httpOnly: true, // Tokens are never readable from client-side JavaScript (XSS defense). 9 secure: process.env.NODE_ENV === 'production', 10 sameSite: 'lax' as const, 11 }; 12 13 export function setSessionCookies(response: NextResponse, tokens: Tokens) { 14 response.cookies.set('sk_id_token', tokens.idToken, { ...COOKIE_BASE, path: '/' }); 15 rotateTokens(response, tokens); 16 } 17 18 // Refresh returns a new access and refresh token but not a new ID token, so this 19 // updates only those two cookies and leaves the existing ID token in place. 20 export function rotateTokens( 21 response: NextResponse, 22 tokens: { accessToken: string; refreshToken: string }, 23 ) { 24 response.cookies.set('sk_access_token', tokens.accessToken, { ...COOKIE_BASE, path: '/' }); 25 // Security: scope the refresh token to the refresh endpoint only, so it is not 26 // attached to every request. This shrinks the window for token exfiltration. 27 response.cookies.set('sk_refresh_token', tokens.refreshToken, { 28 ...COOKIE_BASE, 29 path: '/api/refresh', 30 }); 31 } 32 33 /** 34 * Returns the authenticated user, or null. Call this from Server Components and 35 * Route Handlers (Node.js runtime) — never from Edge middleware, because the 36 * Scalekit SDK needs Node APIs that the Edge runtime does not provide. 37 */ 38 export async function getSession() { 39 const cookieStore = await cookies(); 40 const accessToken = cookieStore.get('sk_access_token')?.value; 41 if (!accessToken) return null; 42 43 const isValid = await scalekit.validateAccessToken(accessToken); 44 if (!isValid) return null; 45 46 // validateToken returns the decoded claims once the signature and expiry pass. 47 const claims = await scalekit.validateToken(accessToken); 48 return { sub: claims.sub, email: claims.email }; 49 } ``` ## Refresh tokens transparently [Section titled “Refresh tokens transparently”](#refresh-tokens-transparently) When the access token expires, redeem the refresh token for a new pair. Because Scalekit rotates refresh tokens, write the new refresh token back immediately and discard the old one. app/api/refresh/route.ts ```ts 1 import { cookies } from 'next/headers'; 2 import { NextResponse } from 'next/server'; 3 import { scalekit } from '@/lib/scalekit'; 4 import { rotateTokens } from '@/lib/session'; 5 6 export async function POST() { 7 const cookieStore = await cookies(); 8 const refreshToken = cookieStore.get('sk_refresh_token')?.value; 9 if (!refreshToken) { 10 return NextResponse.json({ error: 'no_session' }, { status: 401 }); 11 } 12 13 try { 14 const tokens = await scalekit.refreshAccessToken(refreshToken); 15 const response = NextResponse.json({ ok: true }); 16 // Security: persist the rotated refresh token. Replaying the old one fails, 17 // which is how Scalekit detects a stolen, reused token. 18 rotateTokens(response, tokens); 19 return response; 20 } catch { 21 return NextResponse.json({ error: 'refresh_failed' }, { status: 401 }); 22 } 23 } ``` ## Protect routes [Section titled “Protect routes”](#protect-routes) Read the session in a Server Component and redirect unauthenticated visitors. This runs on the Node.js runtime, so the SDK validation works. app/dashboard/page.tsx ```tsx 1 import { redirect } from 'next/navigation'; 2 import { getSession } from '@/lib/session'; 3 4 export default async function DashboardPage() { 5 const session = await getSession(); 6 if (!session) redirect('/login'); 7 8 return

Welcome, {session.email}

; 9 } ``` For a coarse, fast gate across many routes, add middleware that only checks whether a session cookie exists. Keep real validation in the page or Route Handler. middleware.ts ```ts 1 import { NextRequest, NextResponse } from 'next/server'; 2 3 export function middleware(request: NextRequest) { 4 // Presence check only — middleware runs on the Edge runtime and cannot call the 5 // Scalekit SDK. getSession() does the cryptographic validation downstream. 6 const hasSession = request.cookies.has('sk_access_token'); 7 if (!hasSession) { 8 return NextResponse.redirect(new URL('/login', request.url)); 9 } 10 return NextResponse.next(); 11 } 12 13 export const config = { matcher: ['/dashboard/:path*'] }; ``` ## Sign out [Section titled “Sign out”](#sign-out) Build the Scalekit logout URL, clear your cookies, and redirect the browser to Scalekit so the server-side session ends too. Pass the ID token as `idTokenHint` before you clear it. app/logout/route.ts ```ts 1 import { cookies } from 'next/headers'; 2 import { NextResponse } from 'next/server'; 3 import { scalekit } from '@/lib/scalekit'; 4 5 export async function GET() { 6 const cookieStore = await cookies(); 7 const idToken = cookieStore.get('sk_id_token')?.value; 8 9 const logoutUrl = scalekit.getLogoutUrl({ 10 idTokenHint: idToken, 11 postLogoutRedirectUri: 'http://localhost:3000/login', 12 }); 13 14 const response = NextResponse.redirect(logoutUrl); 15 // Clear local cookies after building the logout URL, so the ID token is still 16 // available to tell Scalekit which session to end. 17 response.cookies.delete('sk_access_token'); 18 response.cookies.delete('sk_id_token'); 19 response.cookies.delete('sk_refresh_token'); 20 return response; 21 } ``` ## Verify it works [Section titled “Verify it works”](#verify-it-works) 1. Start the app with `pnpm dev` and open `http://localhost:3000/dashboard`. The middleware redirects you to `/login`. 2. Visit `http://localhost:3000/login`. The browser lands on Scalekit’s hosted login page showing every method you enabled in the dashboard. 3. Sign in. Scalekit returns to `/api/callback`, which sets the session cookies and forwards you to `/dashboard`, where your email renders. 4. Inspect cookies in your browser devtools. Confirm `sk_access_token`, `sk_id_token`, and `sk_refresh_token` are present and marked `HttpOnly`. 5. Open `http://localhost:3000/logout`. Your cookies clear, Scalekit ends the session, and you return to `/login`. ## Production notes [Section titled “Production notes”](#production-notes) * **Encrypt cookie values.** This recipe stores raw tokens for clarity. In production, encrypt them with `SESSION_COOKIE_SECRET` (for example with [`jose`](https://github.com/panva/jose)) before writing, and decrypt on read. * **Drive refresh from the client.** Call `POST /api/refresh` from a client effect shortly before the access token expires, or retry once on a `401`, so sessions renew without a full re-login. * **Use absolute redirect URLs per environment.** Replace the hard-coded `localhost` URLs with an environment variable, and register each environment’s callback and post-logout URLs in the dashboard. When you are ready to ship, walk the [production readiness checklist](/authenticate/launch-checklist/). To inspect what the access token carries, see [ID token claims](/guides/idtoken-claims/). --- # DOCUMENT BOUNDARY --- # Apify Actor with per-user OAuth via Scalekit > Build an Apify Actor that uses Scalekit Agent Auth so each user connects their OAuth accounts, keyed by Apify userId. An Apify Actor is a stateless serverless container. Every run starts cold — no session, no cookies, no “current user.” When you want each person who runs your Actor to access their own Notion workspace, their own Gmail, or their own GitHub account, you need to map Apify’s identity model onto an OAuth token store that persists across runs. Scalekit solves this with a connected-accounts model: for each `(connector, identifier)` pair, it stores one OAuth session and refreshes it automatically. This recipe builds an Actor that connects to Notion per-user and to YouTube via a shared account, using Apify’s native `userId` as the per-user identifier. It also shows how to surface the OAuth consent step as a live interactive page inside the Actor run, instead of a raw link buried in JSON output. **What this recipe covers:** * **Per-user identity without input fields** — derive the connected-account identifier from `Actor.getEnv().userId` so users never type an email or ID * **Shared vs per-user connectors** — hardcode a single identifier for connectors shared across all users; derive one per user for private accounts * **Interactive auth UX** — serve a branded OAuth consent page on Apify’s live-view port so users click a button rather than hunting for a raw URL * **Input schema design** — expose only the `task` field to end users; keep all auth and config internal The complete source is available in the [notion-youtube-agent](https://github.com/scalekit-developers/agentkit-apify-actor-example) repository. ## Before you start [Section titled “Before you start”](#before-you-start) You need working OAuth credentials for each third-party API your Actor will connect to. Scalekit manages the token lifecycle, but the underlying API must be enabled and the OAuth client must exist first. **For YouTube (or any Google API):** 1. Open the [Google Cloud Console](https://console.cloud.google.com/) and select your project. 2. Go to **APIs & Services → Enabled APIs & services** and enable **YouTube Data API v3**. Without this, every tool call returns `permission_denied` even if the OAuth token is valid. 3. Go to **APIs & Services → OAuth consent screen** and add the Google accounts that will authorize the Actor under **Test users**. While the app is in “Testing” publishing status, only accounts listed here can complete the OAuth flow — all others see `Error 403: org_internal`. 4. Create an OAuth 2.0 client (**APIs & Services → Credentials → + Create credentials → OAuth client ID**). Set the application type to **Web application**. Leave the redirect URI blank for now — you’ll add it from Scalekit in the next section. **For Notion:** 1. Go to [notion.so/my-integrations](https://www.notion.so/my-integrations) and create a new integration, or use Notion’s OAuth setup if your Actor uses Scalekit’s Notion OAuth connector. **For both connectors:** * A [Scalekit](https://app.scalekit.com) environment with API credentials (`SCALEKIT_ENV_URL`, `SCALEKIT_CLIENT_ID`, `SCALEKIT_CLIENT_SECRET`). * [Apify CLI](https://docs.apify.com/cli) installed: `npm install -g @apify/cli` * Node.js 18+ ### 1. Set up connections in Scalekit [Section titled “1. Set up connections in Scalekit”](#1-set-up-connections-in-scalekit) In the [Scalekit Dashboard](https://app.scalekit.com), go to **AgentKit → Connections** and create two connections: **YouTube connection (shared)** 1. Search for **YouTube** and click **Create**. 2. Copy the **Redirect URI** from the connection panel (it looks like `https:///sso/v1/oauth//callback`). 3. Paste it into your Google Cloud OAuth client under **Authorized redirect URIs** and save. 4. Back in Scalekit, enter the **Client ID** and **Client Secret** from your Google Cloud OAuth client. 5. Under **Scopes**, select at least `youtube.readonly`. Add `youtube` if your Actor needs write access (playlists, subscriptions). Add `yt-analytics.readonly` if you query analytics data. 6. Click **Save**. Note the **Connection name** (e.g., `youtube`) — your code must match it exactly. **Notion connection (per-user)** 1. Search for **Notion** and click **Create**. 2. Enter the **Client ID** and **Client Secret** from your Notion integration or OAuth app. 3. Scalekit pre-configures the redirect URI and scopes for Notion. Click **Save**. 4. Note the **Connection name** (e.g., `notion`). Scopes are locked at authorization time Scopes are locked in at authorization time. If you add scopes to a connection after a user has already authorized, their existing token does not gain the new scopes. Delete the connected account in Scalekit and have the user re-authorize to pick up the updated scopes. ### 2. Create the Apify Actor project [Section titled “2. Create the Apify Actor project”](#2-create-the-apify-actor-project) ```bash 1 apify create notion-youtube-agent -t project_empty 2 cd notion-youtube-agent 3 npm install @scalekit-sdk/node openai apify ``` Set your Scalekit credentials as Actor environment variables in the Apify Console under **Settings → Environment variables**: ```bash 1 SCALEKIT_ENV_URL=https://your-env.scalekit.dev 2 SCALEKIT_CLIENT_ID=skc_... 3 SCALEKIT_CLIENT_SECRET=your-secret ``` If your Actor creates new Notion pages (not just writing to existing ones), also set a default parent location. Without this, the Actor can only write to pages that already exist by exact title match. ```bash 1 NOTION_DEFAULT_PARENT_PAGE_ID=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d ``` To find a Notion page ID: open the page in Notion, click **Share → Copy link**. The 32-character hex string at the end of the URL is the page ID. ### 3. Derive user identity from Apify’s runtime [Section titled “3. Derive user identity from Apify’s runtime”](#3-derive-user-identity-from-apifys-runtime) Apify exposes the identity of the account running the Actor through `Actor.getEnv()`. Use `userId` directly as the Scalekit connected-account identifier — no email field, no manual input. src/main.js ```js 1 import { Actor } from 'apify'; 2 3 await Actor.init(); 4 5 const { userId } = Actor.getEnv(); 6 7 // userId is stable per Apify account — the same user always gets the same token. 8 const notionIdentifier = userId; ``` `userId` is a stable opaque string that Apify sets for the account running the Actor. It persists across runs, so the first run that completes OAuth will find an active token on every subsequent run. Local development: userId is undefined `Actor.getEnv().userId` is `undefined` when you run the Actor locally with `apify run`. Use a hardcoded fallback for local development: ```js 1 const { userId } = Actor.getEnv(); 2 const notionIdentifier = userId ?? 'local-dev-user'; ``` ### 4. Choose shared vs per-user identifiers [Section titled “4. Choose shared vs per-user identifiers”](#4-choose-shared-vs-per-user-identifiers) Not every connector needs per-user isolation. A YouTube data connection used for research can be shared across all Actor runs with a hardcoded identifier. Only connectors that access private user data need per-user identifiers. src/main.js ```js 1 // Per-user: each Apify account connects their own Notion workspace. 2 const notionIdentifier = userId; 3 4 // Shared: one YouTube OAuth session used by all runs. 5 const youtubeIdentifier = 'shared-youtube'; ``` Hardcode the shared identifier in code — do not expose it as an input field. End users should not need to know it exists. ### 5. Ensure each connector is authorized [Section titled “5. Ensure each connector is authorized”](#5-ensure-each-connector-is-authorized) Before calling any API, check whether the connected account is active. If not, generate a magic link and wait for the user to complete the OAuth flow. src/notionAuth.js ```js 1 import { Actor } from 'apify'; 2 3 const ACTIVE = 1; 4 5 export async function ensureNotionConnected(scalekitActions, identifier, { 6 pollIntervalMs = 5_000, 7 timeoutMs = 300_000, 8 onMagicLink = async () => {}, 9 } = {}) { 10 const resp = await scalekitActions.getOrCreateConnectedAccount({ 11 connectionName: 'notion', 12 identifier, 13 }); 14 const account = resp.connectedAccount ?? resp; 15 16 if (account.status === ACTIVE) { 17 return account.id; 18 } 19 20 const { link } = await scalekitActions.getAuthorizationLink({ 21 connectionName: 'notion', 22 identifier, 23 }); 24 25 const markDone = await onMagicLink(link); 26 27 const deadline = Date.now() + timeoutMs; 28 29 while (Date.now() < deadline) { 30 await sleep(pollIntervalMs); 31 32 const pollResp = await scalekitActions.getOrCreateConnectedAccount({ 33 connectionName: 'notion', 34 identifier, 35 }); 36 const polled = pollResp.connectedAccount ?? pollResp; 37 38 if (polled.status === ACTIVE) { 39 markDone?.(); 40 await Actor.setStatusMessage('Notion authorized — proceeding.'); 41 return polled.id; 42 } 43 } 44 45 throw new Error(`Timed out waiting for Notion authorization.`); 46 } 47 48 function sleep(ms) { 49 return new Promise(resolve => setTimeout(resolve, ms)); 50 } ``` The same pattern applies to every connector. Copy the function, change `connectionName`, and pass in the appropriate identifier. ### 6. Surface auth as a live interactive page [Section titled “6. Surface auth as a live interactive page”](#6-surface-auth-as-a-live-interactive-page) Printing a raw magic link to the console or burying it in JSON output creates a poor experience. Apify Actors can start an HTTP server on `ACTOR_WEB_SERVER_PORT` (default `4321`), and Apify automatically exposes it as a public URL while the run is active. Use this to serve a branded OAuth consent page. src/authServer.js ```js 1 import http from 'http'; 2 import { Actor } from 'apify'; 3 4 const PORT = parseInt(process.env.ACTOR_WEB_SERVER_PORT ?? '4321', 10); 5 6 let server = null; 7 8 export function getLiveViewUrl() { 9 const { actorId, actorRunId } = Actor.getEnv(); 10 return `https://${actorId}--${actorRunId}-${PORT}.runs.apify.net`; 11 } 12 13 export async function serveAuthPage(link, serviceName) { 14 let html = buildAuthPage(link, serviceName); 15 16 if (server) server.close(); 17 server = http.createServer((_req, res) => { 18 res.writeHead(200, { 'Content-Type': 'text/html' }); 19 res.end(html); 20 }); 21 server.listen(PORT); 22 23 return { 24 liveViewUrl: getLiveViewUrl(), 25 markDone: () => { html = buildDonePage(serviceName); }, 26 }; 27 } 28 29 function buildAuthPage(link, serviceName) { 30 return ` 31 32 33 34 Authorize ${serviceName} 35 43 44 45
46

🔐 Connect ${serviceName}

47

Click below to authorize access to your ${serviceName} account. 48 The actor will continue automatically once you complete authorization.

49 Authorize ${serviceName} → 50
51 52 `; 53 } 54 55 function buildDonePage(serviceName) { 56 return ` 57 58 ${serviceName} Authorized 59 60

✅ ${serviceName} Authorized

61

Returning to task — you can close this tab.

62 63 `; 64 } ``` The live view URL follows this pattern: ```text 1 https://{actorId}--{actorRunId}-{PORT}.runs.apify.net ``` Both `actorId` and `actorRunId` come from `Actor.getEnv()` — the same call that gives you `userId`. ### 7. Wire auth into the Actor entry point [Section titled “7. Wire auth into the Actor entry point”](#7-wire-auth-into-the-actor-entry-point) Pass the live view callback into `ensureNotionConnected`. The callback starts the HTTP server, stores the `markDone` function, and returns it so the polling loop can update the page when auth completes. src/main.js ```js 1 import { Actor } from 'apify'; 2 import { ScalekitClient } from '@scalekit-sdk/node'; 3 import { ensureNotionConnected } from './notionAuth.js'; 4 import { serveAuthPage } from './authServer.js'; 5 6 await Actor.init(); 7 8 const input = await Actor.getInput(); 9 const { task } = input; 10 11 const { userId } = Actor.getEnv(); 12 const notionIdentifier = userId; 13 const youtubeIdentifier = 'shared-youtube'; 14 15 const scalekit = new ScalekitClient( 16 process.env.SCALEKIT_ENV_URL, 17 process.env.SCALEKIT_CLIENT_ID, 18 process.env.SCALEKIT_CLIENT_SECRET, 19 ); 20 21 await ensureNotionConnected(scalekit.actions, notionIdentifier, { 22 onMagicLink: async (link) => { 23 const { liveViewUrl, markDone } = await serveAuthPage(link, 'Notion'); 24 25 // Store the live view URL in OUTPUT so the Apify UI shows a clickable link. 26 await Actor.setValue('OUTPUT', { 27 status: 'AWAITING_NOTION_AUTH', 28 authPageUrl: liveViewUrl, 29 message: 'Open authPageUrl in your browser to authorize Notion.', 30 }); 31 32 await Actor.setStatusMessage(`ACTION REQUIRED: Authorize Notion → ${liveViewUrl}`); 33 34 return markDone; 35 }, 36 }); 37 38 // ... run the agent, push results ``` End-user experience after this change: 1. User starts the Actor run and types their task 2. **Output** panel immediately shows a clickable `authPageUrl` 3. User opens the URL and sees a branded “Authorize Notion →” button 4. After completing OAuth, the page updates to ”✅ Notion Authorized” 5. The Actor continues automatically — no re-run needed ### 8. Design the input schema for end users [Section titled “8. Design the input schema for end users”](#8-design-the-input-schema-for-end-users) The Actor’s input form should show only what the end user actually needs to provide. All auth identifiers, LLM config, and internal settings stay out of the form. .actor/input\_schema.json ```json 1 { 2 "title": "Notion + YouTube AI Agent", 3 "type": "object", 4 "schemaVersion": 1, 5 "properties": { 6 "task": { 7 "title": "Task", 8 "type": "string", 9 "description": "Natural language task for the agent. Examples: 'List the 5 most recently edited pages in my Notion workspace' or 'Search YouTube for React tutorial channels and append the top 10 to my Research page'.", 10 "editor": "textarea" 11 } 12 }, 13 "required": ["task"] 14 } ``` By default the Actor uses [Apify’s OpenRouter proxy](https://apify.com/apify/openrouter) for LLM inference, authenticated via `APIFY_TOKEN` (which Apify sets automatically). No external API key is needed — LLM costs are billed to the user’s Apify credits. If your Actor needs to support a custom LLM endpoint, add an optional `llmApiKey` field and detect the endpoint at runtime. Everything else — `notionIdentifier`, `youtubeIdentifier`, timeouts, model name, base URL — is either derived at runtime (`userId`) or hardcoded and deployed as an Actor environment variable. ### 9. Testing [Section titled “9. Testing”](#9-testing) Run locally: ```bash 1 apify run ``` Provide input in `storage/key_value_stores/default/INPUT.json`: ```json 1 { 2 "task": "List the 5 most recently edited pages in my Notion workspace" 3 } ``` Because `Actor.getEnv().userId` is `undefined` locally, the `notionIdentifier` falls back to your local development value. After you confirm the flow works, deploy to Apify: ```bash 1 apify push ``` On the first cloud run, the Actor outputs an `authPageUrl`. Open it, click **Authorize Notion**, and complete the OAuth flow. The Actor polls and continues automatically. On every subsequent run for the same Apify account, the token is already active and the auth step is skipped entirely. ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Production notes [Section titled “Production notes”](#production-notes) **Token persistence across runs** — Scalekit stores the OAuth token server-side keyed by `(connectionName, identifier)`. As long as `userId` is stable (it is), the user only completes the OAuth flow once. Subsequent runs call `getOrCreateConnectedAccount` and get an active account back immediately. **Token refresh** — Scalekit refreshes expired tokens automatically before returning them. You do not need to track expiry or call a refresh endpoint. **Re-authorization** — If a user revokes access in Notion’s settings, `getOrCreateConnectedAccount` returns a non-active account. The Actor generates a new magic link automatically. No code change required — the polling loop handles it the same way as a first-time auth. **Shared connectors** — The `shared-youtube` identifier works because YouTube access is the same for all users (e.g., read-only public data). Any connector where all users share the same OAuth session can use a hardcoded identifier. Private data connectors — Notion, Gmail, GitHub — should always use a per-user identifier. **Input schema changes require a redeploy** — The Apify Console reads the input schema from the deployed build. Changes to `.actor/input_schema.json` only take effect after `apify push`. ## Next steps [Section titled “Next steps”](#next-steps) * **Add more per-user connectors** — The same `ensureConnected` + `onMagicLink` pattern works for any Scalekit connector. Add a `src/githubAuth.js` following the same structure as `notionAuth.js`. * **Use built-in actions** — For connectors with Scalekit built-in tools, replace manual API calls with `scalekit.actions.executeTool`. See [all supported connectors](/agentkit/connectors/). * **Extend the input schema** — Add optional fields like `maxIterations` or `llmModel` with defaults, so power users can tune the Actor without the defaults getting in the way for casual users. * **Review the agent auth quickstart** — For a broader overview of the connected-accounts model, see the [agent auth quickstart](/agentkit/quickstart/). --- # DOCUMENT BOUNDARY --- # Build a Vapi voice assistant with Scalekit > Use Vapi + Scalekit Virtual MCP for voice assistants to securely access any tool from large catalogs. Voice interfaces shine for hands-free, conversational access to data and actions. But giving a voice agent access to real tools (Gmail, Calendar, Slack, GitHub, Drive, CRM, Notion, and [many other connectors](/agentkit/connectors/)) introduces two hard problems: per-user authentication without leaking tokens to the LLM, and managing a large tool surface without overwhelming context windows or exposing everything to every user. Scalekit lets you: * Register built-in tools from connections and custom tools directly in the UI or code (see “Registering tools in the Scalekit UI” below). * Associate them with specific users via connections. * Use **Virtual MCP** to bundle hundreds or thousands of those registered tools into a single, scoped, per-user MCP endpoint that Vapi can discover dynamically. This cookbook walks through building a [Vapi](https://vapi.ai) voice assistant that can safely discover and use any tool (from a catalog of hundreds or thousands) using Scalekit’s tool registration + Virtual MCP. You can also call specific registered tools directly via Vapi Function tools if you don’t need dynamic discovery of many. The complete source is available in the [vapi-scalekit-voice-demo](https://github.com/scalekit-developers/vapi-scalekit-voice-demo) repository. ## What you are building [Section titled “What you are building”](#what-you-are-building) * Register and manage individual tools (built-in from connections or custom) directly in the Scalekit UI, and associate them with users/connections. * A **Vapi voice assistant** that understands natural language requests (e.g. “List my meetings this week”, “Find emails from Acme about the renewal”, “Summarize the last thread in #eng-updates on Slack”, “Show my open GitHub PRs”, “Find the latest proposal in Drive and email it to the team”). * **Dynamic tool discovery** via a Scalekit Virtual MCP — the assistant only sees the tools you explicitly scoped for that role (selected from the ones you registered). Vapi discovers these at call start via the MCP protocol. * **Per-user OAuth without custom code** — Scalekit handles authorization links, token storage, and refresh. Your app passes the user’s identifier. * **Access to any tool** — scoping + per-user tokens keep context small and access least-privilege even when the full catalog is huge. * A pattern you can extend to other voice platforms or agent frameworks by swapping the client. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A Scalekit account with AgentKit enabled ([create one](https://app.scalekit.com)). * At least one connection configured (e.g. Google Calendar, Gmail) under **AgentKit → Connections**. See [Configure a connection](/agentkit/connections/). * A Vapi account and at least one assistant. * Node.js 18+ and the demo dependencies. * ngrok (or equivalent) for local webhook exposure during development. * Familiarity with basic voice agent concepts and OAuth flows. ## Environment variables [Section titled “Environment variables”](#environment-variables) The demo is configured via `.env.local` (copy it from `.env.example`). ```bash 1 cp .env.example .env.local ``` ### Variables present in the demo [Section titled “Variables present in the demo”](#variables-present-in-the-demo) | Variable | Required | Client (browser) | Purpose | | ----------------------------------------- | --------------- | ---------------- | ---------------------------------------------------------------------------------------- | | `NEXT_PUBLIC_VAPI_PUBLIC_KEY` | Yes | Yes | Initializes the Vapi Web SDK in the browser | | `NEXT_PUBLIC_VAPI_ASSISTANT_ID` | Yes | Yes | ID of the assistant to start voice calls against | | `VAPI_PRIVATE_KEY` | For API updates | No | Used server-side only to call Vapi APIs (create/update tools programmatically) | | `SCALEKIT_ENV_URL` | Yes | No | Base URL of your Scalekit environment | | `SCALEKIT_CLIENT_ID` | Yes | No | Scalekit API credential (public part) | | `SCALEKIT_CLIENT_SECRET` | Yes | No | Scalekit secret. Never ship to browser or commit | | `TEST_IDENTIFIER` | Yes | No (server) | The user identity (email / your ID) whose connections will be used | | `NEXT_PUBLIC_TEST_SCALEKIT_CONNECTION_ID` | Yes | Yes | Browser-safe copy of the identifier; passed in Vapi call `metadata` | | `SCALEKIT_MCP_CONFIG_ID` | For MCP | No | `cfg_...` ID of your Virtual MCP config (created in Scalekit dashboard) | | `NEXT_PUBLIC_SCALEKIT_MCP_SERVER_URL` | For MCP | Yes (url only) | The static base MCP server URL. Token is added at runtime via the `Authorization` header | **MCP-specific vars** (`SCALEKIT_MCP_CONFIG_ID` + `NEXT_PUBLIC_SCALEKIT_MCP_SERVER_URL`) are only needed when using the dynamic discovery MCP tool path (recommended when you want to expose many tools). They are not required for pure Function tool + `executeTool` mode. ### Running the token helper (demo) [Section titled “Running the token helper (demo)”](#running-the-token-helper-demo) After filling the MCP variables, generate a fresh token for Vapi: ```bash 1 python scripts/generate-mcp-token.py ``` (or `node --env-file=.env.local scripts/generate-mcp-token.js`) The script outputs the exact `server` object (url + Authorization header) you paste into the Vapi MCP tool form. ### What changes when you go live (production) [Section titled “What changes when you go live (production)”](#what-changes-when-you-go-live-production) In a real application you do **not** rely on a static `.env.local` for user identity or tokens: * **Identifier comes from runtime context** — After a real user authenticates in your app and authorizes their connections (Gmail etc.), you obtain their `identifier` from your session / database. Never use a hardcoded `TEST_IDENTIFIER`. * **Tokens are minted on the fly and short-lived** — When the user starts a voice call, your backend calls Scalekit to create a fresh session token for that specific identifier + config (see `app/api/scalekit/mcp-session/route.ts` and the Python script). Tokens typically live for minutes to an hour. * **MCP server configuration is injected dynamically** — * Demo: you manually copy-paste `server.url` and the `Authorization: Bearer ` header into the Vapi dashboard UI. * Production: your backend uses the **Vapi API** (authenticated with `VAPI_PRIVATE_KEY`) to create or patch the MCP tool on the assistant with the fresh per-call `server` object (containing the just-minted token). You can do this immediately before calling `vapi.start(...)` or via Vapi’s assistant update endpoints. The token never sits in your dashboard. * **Secrets stay server-side** — `SCALEKIT_CLIENT_SECRET` and `VAPI_PRIVATE_KEY` remain in your production environment variables / secret manager. Only non-sensitive values (`NEXT_PUBLIC_*` public keys, config IDs, base URLs) may be exposed to the client when truly required. * For non-MCP flows (Function tools), the webhook receives the identifier via Vapi `metadata` and performs minting + `executeTool` internally. This design means the same Virtual MCP config works for every user—you only swap the short-lived token and the acting identifier at call time. ## Registering tools in the Scalekit UI [Section titled “Registering tools in the Scalekit UI”](#registering-tools-in-the-scalekit-ui) You register and associate tools centrally in the Scalekit dashboard (no code required for built-ins): * **Set up a connection** (AgentKit → Connections): Choose Gmail, Google Calendar, GitHub, etc. Scalekit registers its built-in tools automatically (e.g. `googlecalendar_list_events`). You can browse and search the full catalog under **AgentKit → Tools** or inside the connection page. See the [full list of connectors](/agentkit/connectors/). * **Authorize for users**: Go to **AgentKit → Connected Accounts** (or during first use), authorize using your app’s `identifier` (e.g. `saif.shaik@scalekit.com`). This associates the tools with that user. The connection must show **Active**. * **Custom tools**: Define additional tools in your code (see [Build custom tools](/agentkit/tools/custom-tools)) using `actions.request` to call any provider API. They can be associated with connections and included in scopes. Once registered and associated, these tools are available for: * Direct calls via `executeTool` (e.g. from a Vapi Function tool webhook). * Inclusion in a **Virtual MCP** config so a single MCP endpoint can surface hundreds or thousands safely. This is key when you have many tools: you register/maintain them in the UI or code, then use vMCP to selectively expose subsets to your voice assistant without token bloat or over-privileging. ## Architecture overview [Section titled “Architecture overview”](#architecture-overview) ```plaintext 1 User (voice) 2 │ 3 ▼ 4 Vapi assistant (MCP tool configured) 5 │ (connects with per-user Bearer token) 6 ▼ 7 Scalekit Virtual MCP (scoped to role + user) 8 │ (only exposes allowed tools) 9 ▼ 10 Scalekit AgentKit (token vault + execute) 11 │ 12 ▼ 13 Real connectors (Gmail, Calendar, Slack, GitHub, ... — [many connectors](/agentkit/connectors/)) ``` Key differences from a naive “give the LLM every tool” approach: * Tool surface is defined once in the Virtual MCP config (least privilege). * Context size stays manageable (scoping reduces tokens). * Identity is enforced at the token level (no raw OAuth secrets reach the model or Vapi). ## Step 1: Create a scoped Virtual MCP (select from your registered tools) in Scalekit [Section titled “Step 1: Create a scoped Virtual MCP (select from your registered tools) in Scalekit”](#step-1-create-a-scoped-virtual-mcp-select-from-your-registered-tools-in-scalekit) 1. In the Scalekit dashboard go to **AgentKit → MCP Configs → Create Config**. 2. Give it a name (e.g. “voice-personal-assistant”). 3. Add connection tool mappings for the connectors you want. See the [full list of connectors](/agentkit/connectors/). Example for calendar + email (expand later with Slack, GitHub, Drive, etc.): ```yaml 1 connection_tool_mappings: 2 - connection_name: googlecalendar 3 tools: [googlecalendar_list_events, googlecalendar_create_event] 4 - connection_name: gmail 5 tools: [gmail_fetch_mails, gmail_send_mail] # start small! ``` 4. Save. Copy the **config ID** (e.g. `cfg_...`) and the generated **mcp\_server\_url**. ![Creating a Virtual MCP in the Scalekit dashboard](/.netlify/images?url=_astro%2Fvmcp-scalekit.DzqPxAS8.png\&w=3012\&h=1090\&dpl=6aaa70ad2ea7b40008ad2afd) The screenshot above shows the Scalekit dashboard flow for creating the scoped Virtual MCP. This single config definition is reused for every user. You only change the token you mint at runtime. The scoping here is what lets you safely expose many tools without the LLM seeing everything. ## Step 2: Authorize connections for your test user [Section titled “Step 2: Authorize connections for your test user”](#step-2-authorize-connections-for-your-test-user) For the identifier you will use in the demo (e.g. your email): 1. Go to **AgentKit → Connected Accounts**. 2. Authorize the connections you mapped above. 3. Confirm they show **Active**. If any are inactive, the token mint will fail with a clear error and an auth link. ## Step 3: Wire the Vapi assistant [Section titled “Step 3: Wire the Vapi assistant”](#step-3-wire-the-vapi-assistant) You have two main options in Vapi, depending on whether you want dynamic discovery of many scoped tools or direct calls to specific ones. ### Option A: MCP tool for dynamic discovery (recommended when you have many tools) [Section titled “Option A: MCP tool for dynamic discovery (recommended when you have many tools)”](#option-a-mcp-tool-for-dynamic-discovery-recommended-when-you-have-many-tools) 1. In Vapi, create or edit an assistant. 2. Create a new **MCP** tool (not Function). 3. Configure it with the Scalekit Virtual MCP details: * **Server URL**: the `mcp_server_url` from Step 1 * **HTTP Headers** (look for the **Headers**, **Add Header**, or **Custom Headers** / `server.headers` section in the tool form in the Vapi dashboard): * Key: `Authorization` * Value: `Bearer ` 4. Attach the MCP tool to the assistant. 5. Update the system prompt to tell the model when and how to use tools (example in the demo repo). ![Registering the MCP tool in the Vapi dashboard](/.netlify/images?url=_astro%2Ftool-registration-scalekit.DMPxf1_w.png\&w=2988\&h=1182\&dpl=6aaa70ad2ea7b40008ad2afd) The screenshot above illustrates where to configure the server URL and add the Authorization HTTP header in Vapi’s MCP tool form. ### Option B: Function tool for specific registered tools [Section titled “Option B: Function tool for specific registered tools”](#option-b-function-tool-for-specific-registered-tools) Create a **Function** tool in Vapi pointing to your webhook URL. The tool name must exactly match a tool you have registered or available in Scalekit (e.g. `googlecalendar_list_events`). Your webhook then calls `executeTool` for it. You now have a voice agent that can discover tools dynamically from the scoped MCP (or call specific ones directly). ## Step 4: Mint per-user tokens at runtime (the demo) [Section titled “Step 4: Mint per-user tokens at runtime (the demo)”](#step-4-mint-per-user-tokens-at-runtime-the-demo) See the dedicated [Environment variables](#environment-variables) section above for the full list and demo vs. production guidance. The demo (Next.js + Vapi Web SDK) shows the complete loop for testing: * User clicks “Start Voice Call” and passes `scalekitConnectionId` (the identifier) via Vapi call `metadata`. * The backend (or the helper script) mints a fresh short-lived session token for that identifier + your Virtual MCP config. * You supply the token via the `Authorization: Bearer ...` header so Vapi can connect to the scoped MCP endpoint with the correct identity. For quick local testing use the provided scripts (prominently shown in the demo UI): ```bash 1 python scripts/generate-mcp-token.py ``` See `scripts/generate-mcp-token.py` (recommended), `scripts/generate-mcp-token.js`, `app/api/scalekit/mcp-session/route.ts`, and the demo’s Virtual MCP panel for exact implementation and copyable output. Key pattern (what the script / route produces): ```json 1 { 2 "server": { 3 "url": "https://...scalekit.../mcp/v3/servers/...", 4 "headers": { 5 "Authorization": "Bearer " 6 } 7 } 8 } ``` In the demo you paste the `url` into Vapi’s MCP tool **Server URL** field and add the header manually (see Step 3). The UI and scripts make this easy to copy. ## Production note: tokens and config are injected at runtime [Section titled “Production note: tokens and config are injected at runtime”](#production-note-tokens-and-config-are-injected-at-runtime) In a real application you never manually edit the Vapi dashboard for each user or call: * Your backend mints the token **on the fly** (using the Scalekit SDK or direct call with management token) exactly when the user initiates the voice session. * You then use the Vapi API (authenticated with your `VAPI_PRIVATE_KEY`) to dynamically set or override the MCP tool’s `server` (url + Authorization header) on the assistant before starting the call. * The identifier always comes from the logged-in user context rather than a `TEST_IDENTIFIER` env var. Mint a session token (and build the `mcpConfig`) in your backend before each call. Node.js and Python match the demo stack. Go and Java are omitted — the Vapi demo and Virtual MCP token helpers are Node/Python only, and the high-level `create_session_token` API is currently documented for the Python SDK. * Node.js mint-token.ts ```ts 1 // The Node SDK does not expose actions.mcp.create_session_token yet. 2 // Mint via the management token + REST, as in the demo route. 3 try { 4 // Security: mint a short-lived, per-user token server-side so the credential 5 // never reaches the browser, Vapi dashboard, or the LLM. 6 const managementToken = await scalekit.getClientAccessToken(); 7 const base = process.env.SCALEKIT_ENV_URL!.replace(/\/$/, ''); 8 const tokenRes = await fetch( 9 `${base}/api/v1/actions/mcp/configs/${mcpConfigId}/session-tokens`, 10 { 11 method: 'POST', 12 headers: { 13 Authorization: `Bearer ${managementToken}`, 14 'Content-Type': 'application/json', 15 }, 16 body: JSON.stringify({ 17 identifier: userIdentifier, 18 expiry: '1h', 19 }), 20 }, 21 ); 22 if (!tokenRes.ok) { 23 throw new Error(await tokenRes.text()); 24 } 25 const tokenData = await tokenRes.json(); 26 const token = tokenData.token; 27 28 const mcpConfig = { 29 url: mcpServerUrl, 30 headers: { Authorization: `Bearer ${token}` }, 31 }; 32 33 // Pass mcpConfig to Vapi (via API or call start) 34 } catch (err) { 35 console.error('Token mint failed:', err); 36 } ``` * Python mint\_token.py ```python 1 from datetime import timedelta 2 3 try: 4 # Security: mint a short-lived, per-user token server-side so the credential 5 # never reaches the browser, Vapi dashboard, or the LLM. 6 token_response = scalekit_client.actions.mcp.create_session_token( 7 mcp_config_id=mcp_id, 8 identifier=user_identifier, 9 expiry=timedelta(hours=1), 10 ) 11 12 mcp_config = { 13 "url": mcp_server_url, 14 "headers": {"Authorization": f"Bearer {token_response.token}"}, 15 } 16 17 # use mcp_config with Vapi 18 except Exception as e: 19 print(f"Token mint failed: {e}") ``` The same Virtual MCP config (the `cfg_...` you created) is reused for everyone. Only the short-lived token and acting identifier change per user / per call. This is exactly what the demo’s `/api/scalekit/mcp-session` endpoint and the “In a real app” callout in the demo UI demonstrate. ## Step 5: Test the voice flow [Section titled “Step 5: Test the voice flow”](#step-5-test-the-voice-flow) 1. Start the demo: `npm run dev` + `ngrok http 3000`. 2. Update Vapi tool Server URL to your ngrok + `/api/vapi/webhook` (for the Function fallback) or point the MCP tool at the Scalekit URL + token. 3. In the browser: click **Start Voice Call**. 4. Speak natural requests. A few examples that work well with common scoped tools: **Calendar** * “What do I have on my calendar this week?” * “Find a 30-minute slot tomorrow afternoon for a sync with Priya” * “Add a meeting with the design team on Friday at 2pm” **Email (Gmail)** * “Find emails from Acme Corp” * “Summarize the latest thread with the legal team” * “Draft a polite reply to the last message from Sarah” **Slack** * “Summarize the latest messages in #product channel” * “Any mentions of the launch in Slack this morning?” **GitHub + Drive + cross-tool** * “Show my open pull requests” * “Find the Q3 roadmap in Drive and email a summary to the team” * “Check my calendar for tomorrow and email the attendees the agenda doc from Drive” The assistant should use the discovered tools, execute them via Scalekit (with your identity), and speak the results. Mix and match connectors (see [full list](/agentkit/connectors/)) that you’ve included in your Virtual MCP config. Watch the terminal for `[Vapi Webhook]` or MCP connection logs. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) | Symptom | Likely cause & fix | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | Vapi can’t discover tools | Token expired or missing `Authorization: Bearer ` header. Regenerate and paste fresh. | | ”No connected account” when minting | User hasn’t authorized the connections in the Virtual MCP. Authorize in Scalekit → Connected Accounts. | | Agent ignores tools or hallucinates | System prompt doesn’t instruct tool use, or too many tools in scope. Tighten mappings in Virtual MCP config and strengthen prompt. | | 401 from Scalekit | Wrong identifier or connection not active for the config. Verify with `list_mcp_connected_accounts`. | See the demo repo for more. ## How this gives voice assistants access to any tool [Section titled “How this gives voice assistants access to any tool”](#how-this-gives-voice-assistants-access-to-any-tool) * **Scoping at config time** — the Virtual MCP only advertises the tools you mapped. The LLM never sees the rest of the catalog. * **Per-user tokens** — even when hundreds or thousands of tools exist, each call only carries the user’s authorized subset. * **Dynamic discovery** — Vapi fetches the current allowed tools at the start of the conversation. No static tool list to maintain. * **Token cost control** — fewer tools = dramatically smaller context. A huge catalog would be unusable; a small scoped set (e.g. 5–15 tools) is practical. **Real use case examples that become feasible only with scoping**: A sales rep might get “Gmail + Calendar + Salesforce + Slack” (8-12 tools). An engineer might get “GitHub + Drive + Slack + Gmail”. Both use the *same* underlying catalog, but each voice session only sees what that person is allowed to do. The same pattern works for any voice or chat platform that supports MCP clients. ## Security & compliance notes [Section titled “Security & compliance notes”](#security--compliance-notes) * Raw OAuth tokens never leave Scalekit. * Every tool call is audited with the acting user’s identity. * You can rotate or revoke access per connection without touching the agent. * Virtual MCP gives you an explicit allow-list instead of “all tools the user has ever connected”. ## Next steps & variations [Section titled “Next steps & variations”](#next-steps--variations) * Add more connectors (see the [full list](/agentkit/connectors/)) by extending the Virtual MCP mapping. * Switch voice platforms (replace Vapi with another MCP-capable voice or chat client). * Add a real user login flow so the identifier comes from your session instead of an env var. * Expose the same Virtual MCP to web, mobile, and voice clients from one config. * Combine with Scalekit’s user verification for stronger identity assurance. ## References [Section titled “References”](#references) * [Scalekit Virtual MCP docs](/agentkit/mcp/overview/) * [Vapi](https://vapi.ai) (see [MCP integration](https://docs.vapi.ai/tools/mcp)) * [AgentKit tool calling](/agentkit/tools/overview/) * Demo repo + recording linked above. See the [full demo source](https://github.com/scalekit-developers/vapi-scalekit-voice-demo) and the [Virtual MCP configuration guide](/agentkit/mcp/configure-mcp-server/). --- # DOCUMENT BOUNDARY --- # Building a Custom Organization Switcher > Learn how to build your own organization switcher UI for complete control over multi-tenant user experiences. When users belong to multiple organizations, the default Scalekit organization switcher handles most use cases. However, some applications require deeper integration—a custom switcher embedded directly in your app’s navigation, or a specialized UI that matches your design system. This guide shows you how to build your own organization switcher using Scalekit’s APIs. ## Why build a custom switcher? [Section titled “Why build a custom switcher?”](#why-build-a-custom-switcher) The default Scalekit-hosted switcher works well for most scenarios. Build a custom switcher when you need: * **In-app navigation**: Users switch organizations without leaving your application * **Custom branding**: The switcher matches your application’s design language * **Specialized workflows**: Your app needs org-specific logic during switches * **Reduced redirects**: Avoid sending users through the authentication flow for every switch ## How the custom switcher works [Section titled “How the custom switcher works”](#how-the-custom-switcher-works) Your application handles the entire switching flow: 1. User authenticates through Scalekit and receives a session 2. Your app fetches the user’s organizations via the User Sessions API 3. You render your own organization selector UI 4. When a user selects an organization, your app updates the active context This approach gives you full control over the UI and routing, but requires you to manage session state and organization context within your application. ## Fetch user organizations [Section titled “Fetch user organizations”](#fetch-user-organizations) The User Sessions API returns the `authenticated_organizations` field containing all organizations the user can access. Use this data to populate your switcher UI. * Node.js Express.js ```javascript 1 // Use case: Get user's organizations for your switcher UI 2 // Security: Always validate session ownership before returning org data 3 const session = await scalekit.session.getSession(sessionId); 4 5 // Extract organizations from the session response 6 const organizations = session.authenticated_organizations || []; 7 8 // Render your organization switcher with this data 9 res.json({ organizations }); ``` * Python Flask ```python 1 # Use case: Get user's organizations for your switcher UI 2 # Security: Always validate session ownership before returning org data 3 session = scalekit_client.sessions.get_session(session_id) 4 5 # Extract organizations from the session response 6 organizations = session.get('authenticated_organizations', []) 7 8 # Render your organization switcher with this data 9 return jsonify({'organizations': organizations}) ``` * Go Gin ```go 1 // Use case: Get user's organizations for your switcher UI 2 // Security: Always validate session ownership before returning org data 3 session, err := scalekitClient.Session().GetSession(ctx, sessionId) 4 if err != nil { 5 return err 6 } 7 8 // Extract organizations from the session response 9 organizations := session.AuthenticatedOrganizations 10 11 // Render your organization switcher with this data 12 c.JSON(http.StatusOK, gin.H{"organizations": organizations}) ``` * Java Spring ```java 1 // Use case: Get user's organizations for your switcher UI 2 // Security: Always validate session ownership before returning org data 3 Session session = scalekitClient.sessions().getSession(sessionId); 4 5 // Extract organizations from the session response 6 List organizations = session.getAuthenticatedOrganizations(); 7 8 // Render your organization switcher with this data 9 return ResponseEntity.ok(Map.of("organizations", organizations)); ``` The response includes organization IDs, names, and metadata for each organization the user can access. ## Add domain context [Section titled “Add domain context”](#add-domain-context) Enhance your switcher by displaying which domains are associated with each organization. Use the Domains API to fetch this information. ```javascript 1 // Example: Fetch domains for an organization 2 const domains = await scalekit.domain.listDomains('org_123'); 3 4 // Display "@acme.com" next to the organization name in your UI ``` This helps users quickly identify the correct organization, especially when they belong to organizations with similar names. ## Handle organization selection [Section titled “Handle organization selection”](#handle-organization-selection) When a user selects an organization in your custom switcher, update your application’s context. Store the active organization ID in session storage or a cookie, then use it for subsequent API calls. * Node.js Express.js ```javascript 1 // Use case: Store selected organization and fetch org-specific data 2 app.post('/api/select-organization', async (req, res) => { 3 const { organizationId } = req.body; 4 const sessionId = req.session.scalekitSessionId; 5 6 // Security: Verify the user belongs to this organization 7 const session = await scalekit.session.getSession(sessionId); 8 const hasAccess = session.authenticated_organizations.some( 9 org => org.id === organizationId 10 ); 11 12 if (!hasAccess) { 13 return res.status(403).json({ error: 'Unauthorized' }); 14 } 15 16 // Store the active organization in the user's session 17 req.session.activeOrganizationId = organizationId; 18 19 res.json({ success: true }); 20 }); ``` * Python Flask ```python 1 # Use case: Store selected organization and fetch org-specific data 2 @app.route('/api/select-organization', methods=['POST']) 3 def select_organization(): 4 data = request.get_json() 5 organization_id = data.get('organizationId') 6 session_id = session.get('scalekit_session_id') 7 8 # Security: Verify the user belongs to this organization 9 user_session = scalekit_client.sessions.get_session(session_id) 10 has_access = any( 11 org['id'] == organization_id 12 for org in user_session.get('authenticated_organizations', []) 13 ) 14 15 if not has_access: 16 return jsonify({'error': 'Unauthorized'}), 403 17 18 # Store the active organization in the user's session 19 session['active_organization_id'] = organization_id 20 21 return jsonify({'success': True}) ``` * Go Gin ```go 1 // Use case: Store selected organization and fetch org-specific data 2 func SelectOrganization(c *gin.Context) { 3 var req struct { 4 OrganizationID string `json:"organizationId"` 5 } 6 if err := c.BindJSON(&req); err != nil { 7 c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) 8 return 9 } 10 11 sessionID := c.GetString("scalekitSessionID") 12 13 // Security: Verify the user belongs to this organization 14 session, err := scalekitClient.Session().GetSession(ctx, sessionID) 15 if err != nil { 16 c.JSON(http.StatusInternalServerError, gin.H{"error": "Session error"}) 17 return 18 } 19 20 hasAccess := false 21 for _, org := range session.AuthenticatedOrganizations { 22 if org.ID == req.OrganizationID { 23 hasAccess = true 24 break 25 } 26 } 27 28 if !hasAccess { 29 c.JSON(http.StatusForbidden, gin.H{"error": "Unauthorized"}) 30 return 31 } 32 33 // Store the active organization in the user's session 34 c.SetCookie("activeOrganizationID", req.OrganizationID, 3600, "/", "", true, true) 35 36 c.JSON(http.StatusOK, gin.H{"success": true}) 37 } ``` * Java Spring ```java 1 // Use case: Store selected organization and fetch org-specific data 2 @PostMapping("/api/select-organization") 3 public ResponseEntity selectOrganization( 4 @RequestBody Map request, 5 HttpSession httpSession 6 ) { 7 String organizationId = request.get("organizationId"); 8 String sessionId = (String) httpSession.getAttribute("scalekitSessionId"); 9 10 // Security: Verify the user belongs to this organization 11 Session session = scalekitClient.sessions().getSession(sessionId); 12 boolean hasAccess = session.getAuthenticatedOrganizations().stream() 13 .anyMatch(org -> org.getId().equals(organizationId)); 14 15 if (!hasAccess) { 16 return ResponseEntity.status(HttpStatus.FORBIDDEN) 17 .body(Map.of("error", "Unauthorized")); 18 } 19 20 // Store the active organization in the user's session 21 httpSession.setAttribute("activeOrganizationId", organizationId); 22 23 return ResponseEntity.ok(Map.of("success", true)); 24 } ``` Always verify that the user actually belongs to the organization they’re attempting to switch to. The `authenticated_organizations` array from the session is your source of truth for access control. ## When to use the hosted switcher instead [Section titled “When to use the hosted switcher instead”](#when-to-use-the-hosted-switcher-instead) The default Scalekit-hosted switcher is the right choice when: * You want the quickest implementation with minimal code * Your application doesn’t require in-app organization switching * You’re okay with users navigating through the authentication flow to switch organizations Build a custom switcher when user experience requirements demand deeper integration with your application’s UI and routing. You may refer to our [Sample Org Swithcer ](https://github.com/scalekit-inc/Nextjs-Django-Org-Switcher-Example/tree/main)application to better understand how the API calls enable this custom org switcher that is embedded inside your application. --- # DOCUMENT BOUNDARY --- # Build a multi-agent email triage crew with CrewAI > Use CrewAI multi-agent orchestration with Scalekit-authenticated Gmail tools to scan, classify, and draft replies to emails. CrewAI’s strength is multi-agent orchestration — you define specialized agents and let them collaborate on a shared workflow. But the moment those agents need to call Gmail, Slack, or GitHub on behalf of a real user, you’re stuck managing OAuth tokens, refresh cycles, and per-user credential storage before you write any agent logic. Scalekit eliminates that plumbing. It stores OAuth sessions per user, refreshes tokens automatically, and exposes authenticated tools over MCP. Your CrewAI code never touches a token — it connects to a Scalekit MCP URL and gets back ready-to-use tools. This cookbook builds a three-agent email triage crew: one agent scans unread emails, another classifies them by priority, and a third drafts replies for the high-priority items. All Gmail access goes through Scalekit. **What this recipe covers:** * **Scalekit MCP integration** — get a Virtual MCP Server URL and mint a session token that authenticates Gmail tools for a specific user * **CrewAI MCPServerAdapter** — connect CrewAI to the MCP server so agents can discover and call Gmail tools * **Multi-agent pipeline** — define three agents with distinct roles that run in sequence * **First-run authorization** — handle the OAuth flow when a user hasn’t connected Gmail yet The complete source is available in the [crewai-scalekit-example](https://github.com/scalekit-developers/crewai-scalekit-example) repository. ### 1. Set up Gmail and a Virtual MCP server [Section titled “1. Set up Gmail and a Virtual MCP server”](#1-set-up-gmail-and-a-virtual-mcp-server) New environments do not ship with a Virtual MCP server. Create the Gmail connection and the MCP config **before** you run the sample — otherwise `list_configs` returns an empty list. In the [Scalekit Dashboard](https://app.scalekit.com): 1. Go to **AgentKit** → **Connections** → **Create Connection** and select **Gmail**. 2. Note the **Connection name** — your code references it by this exact string (for example `gmail`). 3. Go to **AgentKit** → **MCP Configs** → **Create** and create a Virtual MCP config (for example `gmail-user-tools`). 4. Attach the Gmail connection and include the tools the crew needs (at least `gmail_fetch_mails`). 5. Copy the **config name** into `SCALEKIT_MCP_CONFIG_NAME` below. For the full API path (create config, mint session tokens, connect agents), see [Set up and connect a Virtual MCP server](/agentkit/mcp/configure-mcp-server/). ### 2. Install dependencies [Section titled “2. Install dependencies”](#2-install-dependencies) ```bash 1 pip install crewai crewai-tools scalekit-sdk-python python-dotenv ``` `crewai-tools` provides `MCPServerAdapter`, which connects CrewAI to any MCP server. `scalekit-sdk-python` generates the authenticated MCP URL for each user. ### 3. Configure credentials [Section titled “3. Configure credentials”](#3-configure-credentials) ```bash 1 cp .env.example .env ``` .env ```bash 1 # Scalekit — get these at app.scalekit.com → Settings → API Credentials 2 SCALEKIT_ENV_URL=https://your-env.scalekit.dev 3 SCALEKIT_CLIENT_ID=skc_... 4 SCALEKIT_CLIENT_SECRET=your-secret 5 6 # User identifier from your application 7 SCALEKIT_USER_IDENTIFIER=user_123 8 9 # Exact Connection name from AgentKit → Connections 10 GMAIL_CONNECTION_NAME=gmail 11 12 # MCP config name — must match the Virtual MCP config created in step 1 13 SCALEKIT_MCP_CONFIG_NAME=gmail-user-tools 14 15 # LLM — any OpenAI-compatible endpoint 16 OPENAI_API_KEY=sk-... ``` ### 4. Initialize Scalekit and ensure authorization [Section titled “4. Initialize Scalekit and ensure authorization”](#4-initialize-scalekit-and-ensure-authorization) ```python 1 import os 2 from scalekit import ScalekitClient 3 from dotenv import find_dotenv, load_dotenv 4 5 load_dotenv(find_dotenv()) 6 7 # Constructor: env_url, client_id, client_secret 8 scalekit_client = ScalekitClient( 9 os.environ["SCALEKIT_ENV_URL"], 10 os.environ["SCALEKIT_CLIENT_ID"], 11 os.environ["SCALEKIT_CLIENT_SECRET"], 12 ) 13 actions = scalekit_client.actions 14 15 USER_ID = os.getenv("SCALEKIT_USER_IDENTIFIER", "user_123") ``` Before calling any Gmail tool, check whether the user has an active connected account. If not, print an authorization link and wait for them to complete OAuth in the browser: ```python 1 # Use the exact Connection name from AgentKit → Connections (not a guessed slug). 2 CONNECTION_NAME = os.getenv("GMAIL_CONNECTION_NAME", "gmail") 3 4 response = actions.get_or_create_connected_account( 5 connection_name=CONNECTION_NAME, 6 identifier=USER_ID, 7 ) 8 connected_account = response.connected_account 9 10 # Do not start the crew until status is ACTIVE. 11 if connected_account.status != "ACTIVE": 12 link = actions.get_authorization_link( 13 connection_name=CONNECTION_NAME, 14 identifier=USER_ID, 15 ) 16 print(f"\n[{CONNECTION_NAME}] Authorization required.") 17 print(f"Open this link:\n\n {link.link}\n") 18 input("Press Enter after authorizing...") 19 response = actions.get_or_create_connected_account( 20 connection_name=CONNECTION_NAME, 21 identifier=USER_ID, 22 ) 23 connected_account = response.connected_account 24 25 if connected_account.status != "ACTIVE": 26 raise RuntimeError( 27 f"{CONNECTION_NAME} is still not ACTIVE. Complete authorization and try again." 28 ) ``` After the first successful authorization, `get_or_create_connected_account` returns an active account on all subsequent runs. Scalekit refreshes expired tokens automatically. ### 5. Connect to Gmail tools via MCP [Section titled “5. Connect to Gmail tools via MCP”](#5-connect-to-gmail-tools-via-mcp) Look up the Virtual MCP config you created in step 1, mint a session token, then pass both to `MCPServerAdapter`. If `list_configs` returns no results, stop and create the config first (dashboard or [configure-mcp-server](/agentkit/mcp/configure-mcp-server/)). Do not assume a default Virtual MCP server exists. ```python 1 from crewai_tools import MCPServerAdapter 2 from datetime import timedelta 3 4 mcp_config_name = os.getenv("SCALEKIT_MCP_CONFIG_NAME", "gmail-user-tools") 5 6 # Retrieve config_id by listing Virtual MCP Servers filtered by name 7 list_response = actions.mcp.list_configs(filter_name=mcp_config_name) 8 if not list_response.configs: 9 raise RuntimeError( 10 f"No Virtual MCP config named '{mcp_config_name}'. " 11 "Create one under AgentKit → MCP Configs (include Gmail tools), " 12 "or follow https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/" 13 ) 14 15 mcp_server_url = list_response.configs[0].mcp_server_url 16 mcp_id = list_response.configs[0].id 17 18 token_response = actions.mcp.create_session_token( 19 mcp_config_id=mcp_id, 20 identifier=USER_ID, 21 expiry=timedelta(hours=1), 22 ) ``` Mint a fresh session token before each agent run. The Virtual MCP Server URL is static — it stays the same across all sessions. CrewAI’s `MCPServerAdapter` connects to the MCP server and discovers all available tools: ```python 1 with MCPServerAdapter({ 2 "url": mcp_server_url, 3 "headers": {"Authorization": f"Bearer {token_response.token}"}, 4 "transport": "streamable-http", 5 }) as tools: 6 # `tools` is a list of CrewAI-compatible tool objects 7 print(f"Discovered {len(tools)} Gmail tools") ``` ### 6. Define the agents [Section titled “6. Define the agents”](#6-define-the-agents) Three agents, each with a specific role. Only the Inbox Scanner needs direct access to Gmail tools — the other agents work with the data it produces: ```python 1 from crewai import Agent, LLM 2 3 llm = LLM( 4 model=os.getenv("LLM_MODEL", "gpt-4o"), 5 base_url=os.getenv("OPENAI_BASE_URL"), 6 api_key=os.getenv("OPENAI_API_KEY"), 7 ) 8 9 scanner = Agent( 10 role="Inbox Scanner", 11 goal="Fetch the user's latest unread emails and extract key metadata.", 12 backstory=( 13 "You are an efficient assistant that reads a Gmail inbox and " 14 "returns a structured summary of unread messages including " 15 "subject, sender, date, and a one-line preview." 16 ), 17 tools=tools, # Gmail tools from MCPServerAdapter 18 llm=llm, 19 verbose=True, 20 ) 21 22 prioritizer = Agent( 23 role="Email Prioritizer", 24 goal="Classify each email by urgency: high, medium, or low.", 25 backstory=( 26 "You are an expert at triaging incoming messages. You consider " 27 "sender importance, subject keywords, and time sensitivity to " 28 "assign a priority level to each email." 29 ), 30 llm=llm, 31 verbose=True, 32 ) 33 34 drafter = Agent( 35 role="Reply Drafter", 36 goal="Draft short, professional replies for high-priority emails.", 37 backstory=( 38 "You are a concise writer who drafts polite, on-point email " 39 "replies. You focus only on high-priority items and keep each " 40 "draft under 100 words." 41 ), 42 llm=llm, 43 verbose=True, 44 ) ``` ### 7. Define tasks and run the crew [Section titled “7. Define tasks and run the crew”](#7-define-tasks-and-run-the-crew) Each task describes what the agent should do and what output to expect. CrewAI runs them in sequence — each task receives the output of the previous one: ```python 1 from crewai import Crew, Process, Task 2 3 scan_task = Task( 4 description=( 5 "Fetch the last 5 unread emails from Gmail. For each email, " 6 "return: subject, sender name, sender email, date, and a " 7 "one-sentence preview of the body." 8 ), 9 expected_output=( 10 "A numbered list of 5 emails with subject, sender, date, " 11 "and preview for each." 12 ), 13 agent=scanner, 14 ) 15 16 prioritize_task = Task( 17 description=( 18 "Take the list of emails from the Inbox Scanner and classify " 19 "each one as high, medium, or low priority. Consider sender " 20 "importance, urgency cues in the subject, and whether the email " 21 "requires a response." 22 ), 23 expected_output=( 24 "The same list of emails, each now tagged with a priority " 25 "level (high / medium / low) and a brief reason." 26 ), 27 agent=prioritizer, 28 ) 29 30 draft_task = Task( 31 description=( 32 "For each email marked as high priority by the Prioritizer, " 33 "draft a short, professional reply (under 100 words). Skip " 34 "medium and low priority emails." 35 ), 36 expected_output=( 37 "A list of draft replies, one per high-priority email, " 38 "including the original subject line and the draft text." 39 ), 40 agent=drafter, 41 ) 42 43 crew = Crew( 44 agents=[scanner, prioritizer, drafter], 45 tasks=[scan_task, prioritize_task, draft_task], 46 process=Process.sequential, 47 verbose=True, 48 ) 49 50 result = crew.kickoff() 51 print(result) ``` ### 8. Run and test [Section titled “8. Run and test”](#8-run-and-test) ```bash 1 python agent.py ``` On first run, you see an authorization prompt: ```text 1 [gmail] Authorization required. 2 Open this link: 3 4 https://auth.scalekit.dev/connect/... 5 6 Press Enter after authorizing... ``` After completing OAuth in the browser and pressing Enter, the crew runs: ```text 1 [ok] Session token minted 2 Discovered 15 Gmail tools 3 4 [Inbox Scanner] Fetching unread emails... 5 [Email Prioritizer] Classifying 5 emails... 6 [Reply Drafter] Drafting replies for 2 high-priority emails... 7 8 ============================================================ 9 CREW RESULT 10 ============================================================ 11 ## High-Priority Emails — Draft Replies 12 13 1. Subject: "Q1 roadmap feedback needed" 14 From: Sarah Chen 15 Priority: HIGH 16 Draft: "Hi Sarah, thanks for flagging this. I'll review the 17 roadmap doc this afternoon and share my comments by EOD." 18 19 2. Subject: "Production incident — action required" 20 From: PagerDuty 21 Priority: HIGH 22 Draft: "Acknowledged. I'm looking into the alert now and will 23 update the incident channel within 15 minutes." ``` On subsequent runs, the authorization step is skipped entirely. ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Production notes [Section titled “Production notes”](#production-notes) **User ID from session** — The sample hardcodes `USER_ID = "user_123"`. In production, replace this with the real user identifier from your application’s session or JWT. A mismatch means Scalekit looks up the wrong user’s Gmail connection. **Token freshness** — Scalekit refreshes expired OAuth tokens before returning them. Mint a fresh session token before each agent run — session tokens are short-lived and scoped to a single run. **MCP server URL is static** — The Virtual MCP Server URL (`mcp_server_url`) is stable and the same for all users. Cache it once per config. Only the session token is per-run. **Rate limits** — Gmail API has per-user daily quotas. If your crew runs frequently, add rate-limiting logic or use Scalekit’s built-in tool pagination to limit the number of emails fetched per run. **Error handling** — In production, wrap `crew.kickoff()` in a try/except to handle LLM failures, MCP connection errors, and tool execution failures gracefully. Log the raw error for debugging. ## Next steps [Section titled “Next steps”](#next-steps) * **Add more connectors** — extend the crew with Slack, GitHub, or Calendar tools. Create additional connections in the dashboard, include them in your MCP config, and pass the expanded tool set to the Scanner agent. See [all supported connectors](/agentkit/connectors/). * **Try the AgentKit CrewAI example** — for a shorter, single-agent version of this pattern, see the [CrewAI example page](/agentkit/examples/crewai/). * **Explore other frameworks** — Scalekit works with LangChain, Google ADK, Vercel AI SDK, and more. See [AgentKit code samples](/agentkit/examples/) for the full list. * **Handle re-authorization** — if a user revokes Gmail access, `get_or_create_connected_account` returns an inactive account. Add a re-authorization path to recover gracefully. * **Review the AgentKit quickstart** — for a broader overview of connections, tools, and MCP, see the [AgentKit quickstart](/agentkit/quickstart/). --- # DOCUMENT BOUNDARY --- # Build a daily briefing agent with Vercel AI SDK and Scalekit Agent Auth > Connect a TypeScript or Python agent via Vercel AI SDK and Scalekit AgentKit to Google Calendar and Gmail with authenticated tool calls. A daily briefing agent needs two things: today’s calendar events and the latest unread emails. Both live behind OAuth-protected APIs, and each requires its own token, its own authorization flow, and its own refresh logic. Before you write any scheduling logic, you’re already maintaining two parallel token lifecycles. Scalekit eliminates that overhead. It stores one OAuth session per connector per user, refreshes tokens automatically, and exposes **built-in tools** such as `googlecalendar_list_events` and `gmail_fetch_mails`. Your agent calls those tools through Scalekit; it never talks to the Google Calendar or Gmail REST APIs directly. **What this recipe covers:** * **Authorize once per connector** — create connected accounts for Calendar and Gmail, open the OAuth link if needed, and wait until status is `ACTIVE` * **Built-in tool calls** — `execute_tool("googlecalendar_list_events")` and `execute_tool("gmail_fetch_mails")` so Scalekit runs the provider call and returns structured data * **Wire both tools into an agent** — Vercel AI SDK (TypeScript) or Anthropic messages (Python) The complete source used here is available in the [vercel-ai-agent-toolkit](https://github.com/scalekit-developers/vercel-ai-agent-toolkit) repository, with a TypeScript implementation using the Vercel AI SDK and a Python implementation using the Anthropic SDK directly. ### 1. Set up connections in Scalekit [Section titled “1. Set up connections in Scalekit”](#1-set-up-connections-in-scalekit) In the [Scalekit Dashboard](https://app.scalekit.com), create two connections under **AgentKit** > **Connections** > **Create Connection**: * `googlecalendar` — Google Calendar OAuth connection * `gmail` — Gmail OAuth connection The connection names are identifiers your code references directly. They must match exactly. ### 2. Install dependencies [Section titled “2. Install dependencies”](#2-install-dependencies) * TypeScript ```bash 1 cd typescript 2 pnpm install ``` The `typescript/package.json` includes: ```json 1 { 2 "dependencies": { 3 "ai": "^4.3.15", 4 "@ai-sdk/anthropic": "^1.2.12", 5 "@scalekit-sdk/node": "2.2.0-beta.1", 6 "zod": "^3.0.0", 7 "dotenv": "^16.0.0" 8 } 9 } ``` * Python ```bash 1 cd python 2 uv venv .venv 3 uv pip install -r requirements.txt ``` The `python/requirements.txt` includes: ```text 1 scalekit-sdk-python 2 anthropic 3 python-dotenv ``` ### 3. Configure credentials [Section titled “3. Configure credentials”](#3-configure-credentials) Copy the example env file and fill in your credentials: ```bash 1 cp typescript/.env.example typescript/.env # TypeScript 2 cp typescript/.env.example python/.env # Python (same variables) ``` .env ```bash 1 SCALEKIT_ENV_URL=https://your-env.scalekit.dev 2 SCALEKIT_CLIENT_ID=skc_... 3 SCALEKIT_CLIENT_SECRET=your-secret 4 5 ANTHROPIC_API_KEY=sk-ant-... ``` Get your Scalekit credentials at **app.scalekit.com → Settings → API Credentials**. ### 4. Initialize the Scalekit client [Section titled “4. Initialize the Scalekit client”](#4-initialize-the-scalekit-client) * TypeScript ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb.js'; 3 import 'dotenv/config'; 4 5 // Never hard-code credentials — they would be exposed in source control. 6 // Pull them from environment variables at runtime. 7 const scalekit = new ScalekitClient( 8 process.env.SCALEKIT_ENV_URL!, 9 process.env.SCALEKIT_CLIENT_ID!, 10 process.env.SCALEKIT_CLIENT_SECRET!, 11 ); 12 const actions = scalekit.actions; 13 14 const USER_ID = 'user_123'; // Replace with the real user ID from your session ``` `ConnectorStatus` is imported from the SDK’s generated protobuf file. Compare `connectedAccount.status` against `ConnectorStatus.ACTIVE` rather than the string `'ACTIVE'` — TypeScript’s type system enforces this. * Python ```python 1 import os 2 import json 3 from datetime import datetime 4 from dotenv import load_dotenv 5 import anthropic 6 from scalekit import ScalekitClient 7 8 load_dotenv() 9 10 # Never hard-code credentials — they would be exposed in source control. 11 # Pull them from environment variables at runtime. 12 # Constructor: env_url, client_id, client_secret 13 scalekit_client = ScalekitClient( 14 os.environ["SCALEKIT_ENV_URL"], 15 os.environ["SCALEKIT_CLIENT_ID"], 16 os.environ["SCALEKIT_CLIENT_SECRET"], 17 ) 18 actions = scalekit_client.actions 19 20 USER_ID = "user_123" # Replace with the real user ID from your session ``` `scalekit_client.actions` is the entry point for connected-account operations and built-in tool execution. ### 5. Ensure each connector is authorized [Section titled “5. Ensure each connector is authorized”](#5-ensure-each-connector-is-authorized) Before calling any API, check whether the user has an active connected account. If not, print an authorization link and wait for them to complete the browser OAuth flow. * TypeScript ```typescript 1 async function ensureConnected(connectionName: string) { 2 let { connectedAccount } = await actions.getOrCreateConnectedAccount({ 3 connectionName, 4 identifier: USER_ID, 5 }); 6 7 // Do not call tools until the user finishes OAuth and status is ACTIVE. 8 if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { 9 const { link } = await actions.getAuthorizationLink({ 10 connectionName, 11 identifier: USER_ID, 12 }); 13 console.log(`\n[${connectionName}] Authorization required.`); 14 console.log(`Open this link:\n\n ${link}\n`); 15 console.log('Press Enter once you have completed the OAuth flow...'); 16 await new Promise(resolve => { 17 process.stdin.resume(); 18 process.stdin.once('data', () => { process.stdin.pause(); resolve(); }); 19 }); 20 21 const refreshed = await actions.getOrCreateConnectedAccount({ 22 connectionName, 23 identifier: USER_ID, 24 }); 25 connectedAccount = refreshed.connectedAccount; 26 } 27 28 if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { 29 throw new Error(`${connectionName} is still not ACTIVE. Complete authorization and try again.`); 30 } 31 32 return connectedAccount; 33 } ``` * Python ```python 1 def ensure_connected(connection_name: str): 2 response = actions.get_or_create_connected_account( 3 connection_name=connection_name, 4 identifier=USER_ID, 5 ) 6 connected_account = response.connected_account 7 8 # Do not call tools until the user finishes OAuth and status is ACTIVE. 9 if connected_account.status != "ACTIVE": 10 link_response = actions.get_authorization_link( 11 connection_name=connection_name, 12 identifier=USER_ID, 13 ) 14 print(f"\n[{connection_name}] Authorization required.") 15 print(f"Open this link:\n\n {link_response.link}\n") 16 input("Press Enter once you have completed the OAuth flow...") 17 response = actions.get_or_create_connected_account( 18 connection_name=connection_name, 19 identifier=USER_ID, 20 ) 21 connected_account = response.connected_account 22 23 if connected_account.status != "ACTIVE": 24 raise RuntimeError( 25 f"{connection_name} is still not ACTIVE. Complete authorization and try again." 26 ) 27 28 return connected_account ``` After the first successful authorization, `getOrCreateConnectedAccount` / `get_or_create_connected_account` returns an active account on all subsequent calls. Scalekit refreshes expired tokens automatically — your code never calls a token-refresh endpoint. ### 6. Fetch calendar events with a built-in tool [Section titled “6. Fetch calendar events with a built-in tool”](#6-fetch-calendar-events-with-a-built-in-tool) Call `execute_tool` with `googlecalendar_list_events`. Scalekit uses the stored OAuth session, calls Google Calendar, and returns structured event data. Your agent never handles a Google access token or the Calendar REST API. * TypeScript ```typescript 1 import { tool } from 'ai'; 2 import { z } from 'zod'; 3 4 const getCalendarEvents = tool({ 5 description: "Fetch today's events from Google Calendar via Scalekit", 6 parameters: z.object({ 7 maxResults: z.number().optional().default(5), 8 }), 9 execute: async ({ maxResults }) => { 10 const response = await actions.executeTool({ 11 toolName: 'googlecalendar_list_events', 12 connectedAccountId: calendarAccount?.id, 13 toolInput: { 14 max_results: maxResults, 15 }, 16 }); 17 // Tool output lives under data — log once when integrating a new tool. 18 return response.data ?? {}; 19 }, 20 }); ``` * Python ```python 1 def fetch_calendar_events(connected_account_id: str, max_results: int = 5) -> dict: 2 response = actions.execute_tool( 3 tool_name="googlecalendar_list_events", 4 connected_account_id=connected_account_id, 5 tool_input={ 6 "max_results": max_results, 7 }, 8 ) 9 # Tool output lives under data — log once when integrating a new tool. 10 return response.data ``` ### 7. Fetch emails with a built-in tool [Section titled “7. Fetch emails with a built-in tool”](#7-fetch-emails-with-a-built-in-tool) Use the same `execute_tool` pattern for Gmail with `gmail_fetch_mails`. Scalekit runs the Gmail API call and returns structured data. * TypeScript ```typescript 1 const getUnreadEmails = tool({ 2 description: 'Fetch top unread emails from Gmail via Scalekit actions', 3 parameters: z.object({ 4 maxResults: z.number().optional().default(5), 5 }), 6 execute: async ({ maxResults }) => { 7 const response = await actions.executeTool({ 8 toolName: 'gmail_fetch_mails', 9 connectedAccountId: gmailAccount?.id, 10 toolInput: { 11 query: 'is:unread', 12 max_results: maxResults, 13 }, 14 }); 15 return response.data ?? {}; 16 }, 17 }); ``` * Python ```python 1 def fetch_unread_emails(connected_account_id: str, max_results: int = 5) -> dict: 2 response = actions.execute_tool( 3 tool_name="gmail_fetch_mails", 4 connected_account_id=connected_account_id, 5 tool_input={ 6 "query": "is:unread", 7 "max_results": max_results, 8 }, 9 ) 10 return response.data ``` You do not need Google Calendar or Gmail API docs for the common path — tool names and parameters are consistent across Scalekit connectors. Browse [all supported agent connectors](/agentkit/connectors/) for the full tool list. ### 8. Wire the agent together [Section titled “8. Wire the agent together”](#8-wire-the-agent-together) Pass both tools to the LLM and ask for a daily summary. * TypeScript The TypeScript version uses the Vercel AI SDK’s `generateText` with `maxSteps` to allow the LLM to call multiple tools in sequence before producing the final response. ```typescript 1 import { generateText } from 'ai'; 2 import { anthropic } from '@ai-sdk/anthropic'; 3 4 const [calendarAccount, gmailAccount] = await Promise.all([ 5 ensureConnected('googlecalendar'), 6 ensureConnected('gmail'), 7 ]); 8 9 const today = new Date(); 10 11 const { text } = await generateText({ 12 model: anthropic('claude-sonnet-4-6'), 13 prompt: `Give me a summary of my day for ${today.toDateString()}: list today's calendar events and my top 5 unread emails.`, 14 tools: { 15 getCalendarEvents, 16 getUnreadEmails, 17 }, 18 maxSteps: 5, // allow the LLM to call multiple tools before responding 19 }); 20 21 console.log(text); ``` `maxSteps` controls how many tool-call rounds the LLM can make before it must return a final text response. Without it, `generateText` stops after the first tool call. * Python The Python version uses the Anthropic SDK directly with a manual agentic loop. The loop continues until the model returns `stop_reason == "end_turn"` with no pending tool calls. ```python 1 def run_agent(): 2 calendar_account = ensure_connected("googlecalendar") 3 gmail_account = ensure_connected("gmail") 4 5 client = anthropic.Anthropic() 6 today = datetime.now().strftime("%A, %B %d, %Y") 7 8 tools = [ 9 { 10 "name": "get_calendar_events", 11 "description": "Fetch today's events from Google Calendar via Scalekit", 12 "input_schema": { 13 "type": "object", 14 "properties": {"max_results": {"type": "integer", "default": 5}}, 15 }, 16 }, 17 { 18 "name": "get_unread_emails", 19 "description": "Fetch top unread emails from Gmail via Scalekit actions", 20 "input_schema": { 21 "type": "object", 22 "properties": {"max_results": {"type": "integer", "default": 5}}, 23 }, 24 }, 25 ] 26 27 messages = [ 28 { 29 "role": "user", 30 "content": f"Give me a summary of my day for {today}: list today's calendar events and my top 5 unread emails.", 31 } 32 ] 33 34 while True: 35 response = client.messages.create( 36 model="claude-sonnet-4-6", 37 max_tokens=1024, 38 tools=tools, 39 messages=messages, 40 ) 41 messages.append({"role": "assistant", "content": response.content}) 42 43 if response.stop_reason == "end_turn": 44 for block in response.content: 45 if hasattr(block, "text"): 46 print(block.text) 47 break 48 49 tool_results = [] 50 for block in response.content: 51 if block.type == "tool_use": 52 max_results = block.input.get("max_results", 5) 53 if block.name == "get_calendar_events": 54 result = fetch_calendar_events(calendar_account.id, max_results) 55 elif block.name == "get_unread_emails": 56 result = fetch_unread_emails(gmail_account.id, max_results) 57 else: 58 result = {"error": f"Unknown tool: {block.name}"} 59 tool_results.append({ 60 "type": "tool_result", 61 "tool_use_id": block.id, 62 "content": json.dumps(result), 63 }) 64 65 if tool_results: 66 messages.append({"role": "user", "content": tool_results}) 67 else: 68 break 69 70 if __name__ == "__main__": 71 run_agent() ``` ### 9. Testing [Section titled “9. Testing”](#9-testing) Run the agent: * TypeScript ```bash 1 cd typescript && pnpm start ``` * Python ```bash 1 cd python && .venv/bin/python index.py ``` On first run, you see two authorization prompts in sequence: ```text 1 [googlecalendar] Authorization required. 2 Open this link: 3 4 https://auth.scalekit.dev/connect/... 5 6 Press Enter once you have completed the OAuth flow... 7 8 [gmail] Authorization required. 9 Open this link: 10 11 https://auth.scalekit.dev/connect/... 12 13 Press Enter once you have completed the OAuth flow... ``` After both connectors are authorized, the agent fetches your data and returns a summary: ```text 1 Here's your day for Friday, March 27, 2026: 2 3 📅 Calendar — 3 events today 4 • 9:00 AM Team standup (30 min) 5 • 1:00 PM Product review 6 • 4:00 PM 1:1 with manager 7 8 📧 Unread emails — top 5 9 • "Q1 roadmap feedback needed" — Sarah Chen, 1h ago 10 • "Deploy failed: production" — GitHub Actions, 2h ago 11 • "New PR review requested" — Lin Feng, 3h ago 12 ... ``` On subsequent runs, both authorization prompts are skipped. Scalekit returns the active session directly. ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Production notes [Section titled “Production notes”](#production-notes) **User ID from session** — Both implementations hardcode `USER_ID = "user_123"`. In production, replace this with the real user identifier from your application’s session. A mismatch means Scalekit looks up the wrong user’s connected accounts. **Token freshness** — Scalekit refreshes OAuth tokens automatically before tool execution. You do not fetch provider tokens or call a refresh endpoint in application code. **First-run blocking** — The authorization prompt blocks the process until the user completes OAuth in the browser. In a web application, redirect the user to `link` instead of printing it, and handle the callback before proceeding. **`execute_tool` response shape** — Tool output lives under `response.data` (Python and Node). Keys inside `data` depend on the tool. Log the raw response once when integrating a new tool, then pass that structure to the LLM. **Rate limits** — Google Calendar and Gmail both enforce per-user quotas. If your agent runs frequently, avoid tight polling loops and cache briefing data where freshness allows. ## Next steps [Section titled “Next steps”](#next-steps) * **Add more connectors** — The same `ensureConnected` + `execute_tool` pattern works for any Scalekit-supported connector. Swap the connection name and tool name. See [all supported connectors](/agentkit/connectors/). * **Need a raw provider call** — Prefer built-in tools first. If a tool does not cover your case, see [proxy API calls](/agentkit/advanced/proxy-api-calls/) rather than extracting tokens in app code. * **Stream the response** — Replace `generateText` with `streamText` in the Vercel AI SDK to stream the LLM’s summary token-by-token instead of waiting for the full response. * **Handle re-authorization** — If a user revokes access, `getOrCreateConnectedAccount` returns an inactive account. Add a re-authorization path to recover gracefully instead of crashing. * **Review the agent auth quickstart** — For a broader overview of the connected-accounts model and supported providers, see the [agent auth quickstart](/agentkit/quickstart/). --- # DOCUMENT BOUNDARY --- # FastRouter + Scalekit tool calling > Build a Node.js agent that routes LLM calls through FastRouter and uses Scalekit for per-user OAuth tools. Build an agent that routes LLM calls through [FastRouter](https://fastrouter.ai). FastRouter provides an OpenAI-compatible chat completions API, so the integration requires only one configuration change: point the OpenAI SDK’s `baseURL` at FastRouter. Scalekit extends that with per-user OAuth tool access, so your agent can read Gmail, create GitHub issues, or post to Slack on behalf of individual users. You can choose from [200+ connectors](/agentkit/connectors/). Scalekit handles OAuth token storage, tool discovery, and tool execution for every connected service. The sample repository is **[fastrouter-scalekit-demo](https://github.com/scalekit-developers/fastrouter-scalekit-demo)** on GitHub. ## What you are building [Section titled “What you are building”](#what-you-are-building) * **FastRouter as the LLM provider** — All chat completions go through FastRouter’s OpenAI-compatible endpoint. Switch models by changing one environment variable. * **Scalekit for tool access** — `listScopedTools` returns per-user tool schemas ready to pass directly to FastRouter. `executeTool` runs each tool server-side and returns structured results. * **B2B OAuth without custom OAuth code** — Scalekit handles the OAuth flow, token storage, and refresh for each connected service. Your agent gets an auth link, waits for the user to authorize, and receives a verified, active connected account. * **Agentic loop** — The agent calls FastRouter, receives tool calls, executes them through Scalekit, and feeds results back — repeating until FastRouter returns a final answer. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * Scalekit account with AgentKit enabled — [create one at app.scalekit.com](https://app.scalekit.com) * At least one AgentKit connection configured (Gmail, GitHub, or Slack) * FastRouter account and API key — [sign up at fastrouter.ai](https://fastrouter.ai) * Node.js 20 or later * For Python code examples: `pip install google-protobuf` (required for tool schema deserialization) ## Clone and run the sample [Section titled “Clone and run the sample”](#clone-and-run-the-sample) 1. **Clone the repository and install dependencies.** ```sh 1 git clone https://github.com/scalekit-developers/fastrouter-scalekit-demo 2 cd fastrouter-scalekit-demo 3 npm install ``` 2. **Copy the example environment file and fill in your credentials.** ```sh 1 cp .env.example .env ``` Open `.env` and set these values: ```sh 1 # Scalekit — find these in your Scalekit dashboard under API Keys 2 SCALEKIT_ENV_URL=https://your-env.scalekit.dev 3 SCALEKIT_CLIENT_ID=your_client_id 4 SCALEKIT_CLIENT_SECRET=your_client_secret 5 6 # The AgentKit connection to use — must match a connection name in your dashboard 7 SCALEKIT_CONNECTION_NAME=gmail 8 9 # FastRouter — find your API key at fastrouter.ai/dashboard 10 FASTROUTER_API_KEY=sk-v1-... 11 FASTROUTER_MODEL=openai/gpt-4o-mini ``` `SCALEKIT_CONNECTION_NAME` must match the exact connection name in your Scalekit dashboard under **AgentKit → Connections**. 3. **Run the agent.** ```sh 1 npm start ``` 4. **Authorize the connection on first run.** The agent prints an authorization link if the connected account is not yet active: ```plaintext 1 Authorization required. 2 Open this link and complete the flow: 3 4 https://your-env.scalekit.dev/magicLink/... 5 6 Waiting for callback on http://localhost:3000/callback ... ``` Open the link in your browser and complete the OAuth flow. The agent detects the callback automatically and continues — no manual step required. After authorization, the agent loads tools, calls FastRouter, and prints a final answer: ```plaintext 1 Connected account is now active. 2 Loaded 17 scoped tools from Scalekit. 3 Model requested 1 tool call(s). 4 5 → Executing gmail_list_messages 6 args: {"maxResults":5,"q":"is:unread"} 7 8 Final answer: 9 10 Here are your 5 most recent unread emails: ... ``` ## How the agent works [Section titled “How the agent works”](#how-the-agent-works) Three pieces connect FastRouter to Scalekit tools. ### B2B OAuth connects user accounts without custom token code [Section titled “B2B OAuth connects user accounts without custom token code”](#b2b-oauth-connects-user-accounts-without-custom-token-code) Scalekit handles the full OAuth flow. Your agent calls `getOrCreateConnectedAccount` to check whether the user’s account is already connected, then calls `getAuthorizationLink` to get an auth URL if it isn’t. * Node.js ```typescript 1 import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; 2 import crypto from 'node:crypto'; 3 4 const connectionName = process.env.SCALEKIT_CONNECTION_NAME; 5 if (!connectionName) { 6 throw new Error('SCALEKIT_CONNECTION_NAME is required'); 7 } 8 9 const userVerifyUrl = 'http://localhost:3000/callback'; 10 11 // Generate a random state value and store it (e.g. in a secure cookie or session) 12 // to validate on the OAuth callback and prevent CSRF / account mix-up attacks. 13 const state = crypto.randomUUID(); 14 15 const { connectedAccount } = await scalekit.actions.getOrCreateConnectedAccount({ 16 connectionName, 17 identifier: 'user_123', 18 userVerifyUrl, 19 }); 20 21 if (connectedAccount?.status !== ConnectorStatus.ACTIVE) { 22 const { link } = await scalekit.actions.getAuthorizationLink({ 23 connectionName, 24 identifier: 'user_123', 25 userVerifyUrl, 26 state, 27 }); 28 // Show link to user, then wait for the browser redirect callback 29 } ``` * Python ```python 1 import os 2 import secrets 3 4 connection_name = os.environ["SCALEKIT_CONNECTION_NAME"] 5 user_verify_url = "http://localhost:3000/callback" 6 7 # Generate and store a state value (e.g. in a secure, HTTP-only cookie) for CSRF protection 8 state = secrets.token_urlsafe(32) 9 10 response = scalekit_client.actions.get_or_create_connected_account( 11 connection_name=connection_name, 12 identifier="user_123", 13 user_verify_url=user_verify_url, 14 ) 15 16 if response.connected_account.status != "ACTIVE": 17 link_resp = scalekit_client.actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier="user_123", 20 user_verify_url=user_verify_url, 21 state=state, 22 ) 23 # Show link_resp.link to the user ``` `userVerifyUrl` is where Scalekit redirects the user’s browser after the OAuth flow completes (GET request with `auth_request_id` and `state` query parameters). The sample runs a minimal HTTP server on `localhost:3000` to catch that redirect, validate the `state` against the original value, extract the `auth_request_id`, and call `verifyConnectedAccountUser` to mark the account active: * Node.js ```typescript 1 async function waitForCallback(port: number, expectedState: string): Promise { 2 return new Promise((resolve, reject) => { 3 const server = http.createServer((req, res) => { 4 const url = new URL(req.url ?? '/', `http://localhost:${port}`); 5 const authRequestId = url.searchParams.get('auth_request_id'); 6 const returnedState = url.searchParams.get('state'); 7 8 res.writeHead(200, { 'Content-Type': 'text/html' }); 9 res.end('

Authorization complete — return to your terminal.

'); 10 server.close(); 11 12 if (authRequestId && returnedState === expectedState) { 13 resolve(authRequestId); 14 } else { 15 reject(new Error('Invalid or missing auth_request_id or state in callback')); 16 } 17 }); 18 server.listen(port); 19 }); 20 } 21 22 const authRequestId = await waitForCallback(3000, state); 23 await scalekit.actions.verifyConnectedAccountUser({ 24 authRequestId, 25 identifier: 'user_123', 26 }); ``` * Python ```python 1 # In your web framework callback handler (e.g. FastAPI): 2 # 1. Validate that the "state" query param matches the value you stored earlier 3 # 2. Then exchange the auth_request_id (never trust identity from the URL alone) 4 5 result = scalekit_client.actions.verify_connected_account_user( 6 auth_request_id=auth_request_id, 7 identifier="user_123", 8 ) 9 # redirect to result.post_user_verify_redirect_url ``` ### Tool discovery returns schemas in FastRouter’s expected format [Section titled “Tool discovery returns schemas in FastRouter’s expected format”](#tool-discovery-returns-schemas-in-fastrouters-expected-format) `listScopedTools` returns only the tools the connected account has permission to use. Map each tool’s `input_schema` to the `parameters` field FastRouter expects: ```typescript 1 const { tools } = await scalekit.tools.listScopedTools('user_123', { 2 filter: { connectionNames: [connectionName] }, 3 pageSize: 100, 4 }); 5 6 const fastRouterTools = tools 7 .map((t) => t.tool?.definition) 8 .filter((def): def is NonNullable => Boolean(def?.name)) 9 .map((def) => ({ 10 type: 'function' as const, 11 function: { 12 name: String(def.name), 13 description: String(def.description ?? ''), 14 parameters: def.input_schema ?? { type: 'object', properties: {} }, 15 }, 16 })); ``` FastRouter uses the same function-calling format as OpenAI. No additional schema transformation is needed. ### The agentic loop runs until the model stops requesting tools [Section titled “The agentic loop runs until the model stops requesting tools”](#the-agentic-loop-runs-until-the-model-stops-requesting-tools) Pass the tool list to FastRouter and execute each tool call through Scalekit until the model returns a response with no tool calls: ```typescript 1 const messages: OpenAI.ChatCompletionMessageParam[] = [ 2 { role: 'system', content: 'You are a helpful assistant. Use tools when they help. Do not invent tool results.' }, 3 { role: 'user', content: 'Fetch my last 5 unread emails and summarize them.' }, 4 ]; 5 6 for (let turn = 0; turn < 8; turn++) { 7 const response = await fastRouter.chat.completions.create({ 8 model: 'openai/gpt-4o-mini', 9 messages, 10 tools: fastRouterTools, 11 tool_choice: 'auto', 12 }); 13 14 const message = response.choices[0].message; 15 messages.push(message); 16 17 // No tool calls means a final answer 18 if (!message.tool_calls?.length) { 19 console.log(message.content); 20 return; 21 } 22 23 // Execute each tool call and append the result 24 for (const call of message.tool_calls) { 25 const result = await scalekit.actions.executeTool({ 26 toolName: call.function.name, 27 identifier: 'user_123', 28 connector: connectionName, 29 toolInput: JSON.parse(call.function.arguments), 30 }); 31 32 messages.push({ 33 role: 'tool', 34 tool_call_id: call.id, 35 content: JSON.stringify(result.data ?? {}), 36 }); 37 } 38 } ``` `executeTool` runs the tool server-side using the connected account’s stored OAuth tokens. Your agent never handles raw access tokens. ## Customize the agent [Section titled “Customize the agent”](#customize-the-agent) **Change the connection.** Set `SCALEKIT_CONNECTION_NAME` to any connection configured in your Scalekit dashboard: | Value | What it connects | | -------- | ----------------------------------- | | `gmail` | Gmail read/send | | `github` | Repositories, issues, pull requests | | `slack` | Channels, messages, users | **Change the model.** Set `FASTROUTER_MODEL` in `.env` to any model FastRouter supports. The agent uses the same code regardless of which model you choose. **Change the prompt.** Pass a prompt as a CLI argument to override the default: ```sh 1 npm start "List all GitHub pull requests assigned to me" ``` Or set `USER_PROMPT` in `.env` to change the default. **Support multiple connections.** Call `listScopedTools` with multiple connection names to give the model tools from all of them at once: ```typescript 1 const { tools } = await scalekit.tools.listScopedTools('user_123', { 2 filter: { connectionNames: ['gmail', 'github', 'slack'] }, 3 }); ``` ## Next steps [Section titled “Next steps”](#next-steps) * **[Scalekit overview](/agentkit/connections)** — Understand connected accounts, tool discovery, and tool execution in depth. * **[AgentKit connections](/agentkit/connectors)** — Set up Gmail, GitHub, Slack, and other connections. * **[OpenAI example](/agentkit/examples/openai)** — See the same tool-calling pattern with OpenAI directly. * **[LiteLLM inbox triage cookbook](/cookbooks/litellm-agentkit-inbox-triage)** — A more complex multi-connection agent with a web approval interface. --- # DOCUMENT BOUNDARY --- # Implement passwordless auth in Next.js 15 > Add magic link and OTP authentication to your Next.js application using Scalekit's headless API. Next.js 15’s App Router expects authentication to be server-first: tokens generated on the server, verification happening in Route Handlers or Server Actions, and sessions stored in HttpOnly cookies. If you’re building passwordless authentication (magic links + OTP), traditional client-side SDKs won’t work properly with this model. This cookbook shows you how to implement passwordless auth that works natively with Next.js 15’s architecture using Scalekit’s headless API. ## The problem [Section titled “The problem”](#the-problem) You want passwordless authentication in Next.js 15 but face these challenges: * **Client-side SDKs break App Router patterns** - They expect browser-side token handling, which violates server-first principles * **Vendor UIs don’t match your design** - Pre-built login pages force you to compromise on branding * **DIY is complex** - Building secure token generation, email delivery, verification, and session management from scratch is a significant lift * **Cross-device failures** - Magic links often break when users switch devices or email clients strip parameters ## Who needs this [Section titled “Who needs this”](#who-needs-this) This cookbook is for you if: * ✅ You’re building a Next.js 15 application using App Router * ✅ You want passwordless authentication (magic links, OTP, or both) * ✅ You need full control over your login UI and email design * ✅ You don’t want to migrate your existing user database * ✅ You require server-side security for compliance You **don’t** need this if: * ❌ You’re happy with vendor-hosted login pages * ❌ You’re using Next.js Pages Router (not App Router) * ❌ You prefer traditional username/password authentication ## The solution [Section titled “The solution”](#the-solution) Scalekit’s passwordless API provides three server-side methods that integrate directly with Next.js 15’s architecture: 1. **`sendPasswordlessEmail()`** - Generates and sends magic link/OTP to user’s email 2. **`verifyPasswordlessEmail()`** - Validates the token/code and returns verified identity 3. **`resendPasswordlessEmail()`** - Issues a fresh credential if the first expires All security logic stays server-side, works with Server Actions and Route Handlers, and integrates with Edge Middleware for route protection. ## Implementation [Section titled “Implementation”](#implementation) ### 1. Configure Scalekit dashboard [Section titled “1. Configure Scalekit dashboard”](#1-configure-scalekit-dashboard) Enable passwordless authentication in your [Scalekit dashboard](https://app.scalekit.com/): 1. Navigate to **Authentication → Passwordless** 2. Select **Magic Link + Verification Code** for maximum reliability 3. Set **Expiry Period** (e.g., 600 seconds for 10-minute lifetime) 4. Enable **Enforce same browser origin** to prevent link hijacking 5. (Optional) Enable **Regenerate credentials on resend** to invalidate old links ### 2. Install dependencies and configure environment [Section titled “2. Install dependencies and configure environment”](#2-install-dependencies-and-configure-environment) ```bash 1 npm install @scalekit-sdk/node jsonwebtoken ``` Create `.env.local`: ```bash 1 SCALEKIT_ENVIRONMENT_URL=env_xxxx 2 SCALEKIT_CLIENT_ID=skc_xxx 3 SCALEKIT_CLIENT_SECRET=your_secret 4 APP_URL=http://localhost:3000 5 JWT_SECRET=your_jwt_secret ``` ### 3. Create session management utilities [Section titled “3. Create session management utilities”](#3-create-session-management-utilities) Create `lib/session-store.ts` to handle server-side session creation: ```typescript 1 import jwt from 'jsonwebtoken'; 2 import { cookies } from 'next/headers'; 3 4 const COOKIE = 'session'; 5 const SECRET = process.env.JWT_SECRET!; 6 7 export function createSession(email: string) { 8 const token = jwt.sign({ email }, SECRET, { expiresIn: '7d' }); 9 cookies().set(COOKIE, token, { 10 httpOnly: true, 11 secure: process.env.NODE_ENV === 'production', 12 sameSite: 'lax', 13 path: '/', 14 maxAge: 60 * 60 * 24 * 7, 15 }); 16 } 17 18 export function readSessionEmail(): string | null { 19 const token = cookies().get(COOKIE)?.value; 20 if (!token) return null; 21 22 try { 23 const decoded = jwt.verify(token, SECRET) as { email: string }; 24 return decoded.email; 25 } catch { 26 return null; 27 } 28 } 29 30 export function clearSession() { 31 cookies().delete(COOKIE); 32 } ``` ### 4. Create send email endpoint [Section titled “4. Create send email endpoint”](#4-create-send-email-endpoint) Create `app/api/auth/send-passwordless/route.ts`: ```typescript 1 import Scalekit from '@scalekit-sdk/node'; 2 import { NextRequest, NextResponse } from 'next/server'; 3 4 const scalekit = new Scalekit( 5 process.env.SCALEKIT_ENVIRONMENT_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET! 8 ); 9 10 export async function POST(req: NextRequest) { 11 const { email } = await req.json(); 12 13 try { 14 const response = await scalekit.passwordless.sendPasswordlessEmail(email, { 15 template: 'SIGNIN', 16 expiresIn: 600, // 10 minutes 17 state: crypto.randomUUID(), 18 magiclinkAuthUri: `${process.env.APP_URL}/api/auth/verify`, 19 }); 20 21 return NextResponse.json({ 22 authRequestId: response.authRequestId, 23 expiresAt: response.expiresAt, 24 }); 25 } catch (error) { 26 return NextResponse.json( 27 { error: 'Failed to send email' }, 28 { status: 500 } 29 ); 30 } 31 } ``` ### 5. Create verification endpoint [Section titled “5. Create verification endpoint”](#5-create-verification-endpoint) Create `app/api/auth/verify/route.ts` with both GET (magic link) and POST (OTP) handlers: ```typescript 1 import Scalekit from '@scalekit-sdk/node'; 2 import { NextRequest, NextResponse } from 'next/server'; 3 import { createSession } from '@/lib/session-store'; 4 5 const scalekit = new Scalekit( 6 process.env.SCALEKIT_ENVIRONMENT_URL!, 7 process.env.SCALEKIT_CLIENT_ID!, 8 process.env.SCALEKIT_CLIENT_SECRET! 9 ); 10 11 // Magic link verification 12 export async function GET(req: NextRequest) { 13 const url = new URL(req.url); 14 const linkToken = url.searchParams.get('link_token'); 15 const authRequestId = url.searchParams.get('auth_request_id') ?? undefined; 16 17 if (!linkToken) { 18 return NextResponse.redirect( 19 new URL('/login?error=missing_token', req.url) 20 ); 21 } 22 23 try { 24 const verified = await scalekit.passwordless.verifyPasswordlessEmail( 25 { linkToken }, 26 authRequestId 27 ); 28 29 createSession(verified.email); 30 return NextResponse.redirect(new URL('/dashboard', req.url)); 31 } catch { 32 return NextResponse.redirect( 33 new URL('/login?error=verification_failed', req.url) 34 ); 35 } 36 } 37 38 // OTP verification 39 export async function POST(req: NextRequest) { 40 const { code, authRequestId } = await req.json(); 41 42 if (!code || !authRequestId) { 43 return NextResponse.json( 44 { error: 'Missing required fields' }, 45 { status: 400 } 46 ); 47 } 48 49 try { 50 const verified = await scalekit.passwordless.verifyPasswordlessEmail( 51 { code }, 52 authRequestId 53 ); 54 55 createSession(verified.email); 56 return NextResponse.json({ success: true }); 57 } catch { 58 return NextResponse.json( 59 { error: 'Invalid or expired code' }, 60 { status: 400 } 61 ); 62 } 63 } ``` ### 6. Add resend endpoint [Section titled “6. Add resend endpoint”](#6-add-resend-endpoint) Create `app/api/auth/resend-passwordless/route.ts`: ```typescript 1 import Scalekit from '@scalekit-sdk/node'; 2 import { NextRequest, NextResponse } from 'next/server'; 3 4 const scalekit = new Scalekit( 5 process.env.SCALEKIT_ENVIRONMENT_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET! 8 ); 9 10 export async function POST(req: NextRequest) { 11 const { authRequestId } = await req.json(); 12 13 if (!authRequestId) { 14 return NextResponse.json( 15 { error: 'Missing authRequestId' }, 16 { status: 400 } 17 ); 18 } 19 20 try { 21 const response = await scalekit.passwordless.resendPasswordlessEmail( 22 authRequestId 23 ); 24 25 return NextResponse.json({ 26 authRequestId: response.authRequestId, 27 expiresAt: response.expiresAt, 28 }); 29 } catch { 30 return NextResponse.json( 31 { error: 'Resend failed' }, 32 { status: 400 } 33 ); 34 } 35 } ``` ### 7. Protect routes with middleware [Section titled “7. Protect routes with middleware”](#7-protect-routes-with-middleware) Create `middleware.ts` in your project root: ```typescript 1 import { NextRequest, NextResponse } from 'next/server'; 2 3 export function middleware(req: NextRequest) { 4 const protectedPath = req.nextUrl.pathname.startsWith('/dashboard'); 5 const hasSession = Boolean(req.cookies.get('session')?.value); 6 7 if (protectedPath && !hasSession) { 8 const url = new URL('/login', req.url); 9 url.searchParams.set('next', req.nextUrl.pathname); 10 return NextResponse.redirect(url); 11 } 12 13 return NextResponse.next(); 14 } 15 16 export const config = { 17 matcher: ['/dashboard/:path*'], 18 }; ``` ### 8. Build login UI (example) [Section titled “8. Build login UI (example)”](#8-build-login-ui-example) Create `app/login/page.tsx`: ```typescript 1 'use client'; 2 3 import { useState } from 'react'; 4 import { useRouter } from 'next/navigation'; 5 6 export default function LoginPage() { 7 const [email, setEmail] = useState(''); 8 const [authRequestId, setAuthRequestId] = useState(''); 9 const [showOtp, setShowOtp] = useState(false); 10 const [otp, setOtp] = useState(''); 11 const router = useRouter(); 12 13 async function handleSendEmail(e: React.FormEvent) { 14 e.preventDefault(); 15 16 const res = await fetch('/api/auth/send-passwordless', { 17 method: 'POST', 18 headers: { 'Content-Type': 'application/json' }, 19 body: JSON.stringify({ email }), 20 }); 21 22 const data = await res.json(); 23 setAuthRequestId(data.authRequestId); 24 setShowOtp(true); 25 } 26 27 async function handleVerifyOtp(e: React.FormEvent) { 28 e.preventDefault(); 29 30 const res = await fetch('/api/auth/verify', { 31 method: 'POST', 32 headers: { 'Content-Type': 'application/json' }, 33 body: JSON.stringify({ code: otp, authRequestId }), 34 }); 35 36 if (res.ok) { 37 router.push('/dashboard'); 38 } 39 } 40 41 return ( 42
43 {!showOtp ? ( 44
45 setEmail(e.target.value)} 49 placeholder="Enter your email" 50 required 51 /> 52 53
54 ) : ( 55
56

Check your email for a magic link or enter the code below:

57 setOtp(e.target.value)} 61 placeholder="Enter 6-digit code" 62 maxLength={6} 63 /> 64 65
66 )} 67
68 ); 69 } ``` ## Security features [Section titled “Security features”](#security-features) Scalekit enforces these protections automatically: * **Rate limiting**: 2 emails per minute per address, 5 OTP attempts per 10 minutes * **Short-lived tokens**: Configure expiry from 60 seconds to 1 hour * **Same-browser enforcement**: When enabled, links can only be verified from the originating browser * **HttpOnly sessions**: Tokens never touch client JavaScript ## Error handling [Section titled “Error handling”](#error-handling) Map Scalekit errors to user-friendly messages: ```typescript 1 function getErrorMessage(error: string): string { 2 if (error.includes('expired')) { 3 return 'This link has expired. Request a new one.'; 4 } 5 if (error.includes('rate')) { 6 return 'Too many attempts. Please try again later.'; 7 } 8 if (error.includes('invalid')) { 9 return 'Invalid code. Please check and try again.'; 10 } 11 return 'Verification failed. Please try again.'; 12 } ``` ## Production checklist [Section titled “Production checklist”](#production-checklist) Before deploying: * ✅ Set `secure: true` for session cookies (enforced automatically in production) * ✅ Configure production Scalekit credentials in environment variables * ✅ Verify dashboard settings match your security requirements * ✅ Test magic link + OTP flow on multiple email clients * ✅ Set up monitoring for authentication errors and rate limit hits * ✅ Configure custom email templates with your branding ## Complete example [Section titled “Complete example”](#complete-example) Full working code is available in the [Scalekit GitHub repository](https://github.com/scalekit-developers/blogops-app-examples/tree/main/nextjs-passwordless-auth). ## Why this approach works [Section titled “Why this approach works”](#why-this-approach-works) This implementation: * **Works natively with App Router** - All sensitive operations are server-side * **Maintains full UI control** - No vendor widgets or redirects to hosted pages * **Handles cross-device gracefully** - OTP fallback covers magic link failures * **Requires no user migration** - Works on top of your existing user store * **Stays secure by default** - HttpOnly cookies, server-only verification, automatic rate limiting ## Related resources [Section titled “Related resources”](#related-resources) * [Scalekit Passwordless Auth Documentation](https://docs.scalekit.com/passwordless/) * [Next.js 15 App Router Documentation](https://nextjs.org/docs/app) * [Full tutorial blog post](https://www.scalekit.com/blog/passwordless-authentication-next-js) --- # DOCUMENT BOUNDARY --- # Configuring JWT Validation Timeouts in Spring Boot 4.0+ > Fix connection timeout errors when validating Scalekit JWT tokens in Spring Boot 4.0.0 and later versions. If you’re using Spring Boot 4.0.0 or later and experiencing connection timeout errors when validating JWT tokens from Scalekit, you’ll need to explicitly configure timeout values. This is a known issue affecting Spring Security’s OAuth2 resource server configuration. ## The problem [Section titled “The problem”](#the-problem) Your Spring Boot application successfully configures the `issuer-uri` for JWT validation: ```yaml 1 spring: 2 security: 3 oauth2: 4 resourceserver: 5 jwt: 6 issuer-uri: https://auth.scalekit.com ``` But authentication fails with timeout errors like: ```plaintext 1 java.net.SocketTimeoutException: Connect timed out 2 at org.springframework.security.oauth2.jwt.JwtDecoders.fromIssuerLocation ``` ## Why this happens [Section titled “Why this happens”](#why-this-happens) Starting with Spring Boot 4.0.0, Spring Security changed how it handles HTTP connections during JWT validation: * **Before 4.0.0**: Spring used default system timeouts (often much longer) * **After 4.0.0**: Spring enforces strict, short timeout defaults that can be too aggressive for production When your application starts or validates its first JWT token, Spring Security: 1. Fetches the OpenID Connect discovery document from `issuer-uri` 2. Retrieves the JWKS (JSON Web Key Set) to verify token signatures 3. Caches these for future validations If these initial requests timeout, authentication fails completely. ## Who needs this fix [Section titled “Who needs this fix”](#who-needs-this-fix) This issue specifically affects: * ✅ Spring Boot applications version **4.0.0 or later** * ✅ Using `issuer-uri` for JWT validation (not manual `jwk-set-uri`) * ✅ Production environments with network latency or firewall rules * ✅ Applications experiencing intermittent authentication failures You **don’t** need this if: * ❌ Using Spring Boot 3.x or earlier * ❌ Manually configuring `jwk-set-uri` instead of `issuer-uri` * ❌ Already have custom `RestTemplate` or `WebClient` configurations ## The solution [Section titled “The solution”](#the-solution) For Spring Security servlet resource servers, there are no properties to configure JWT discovery/JWKS HTTP timeouts. Use a custom `JwtDecoder` bean with `RestOperations` (for example, `RestTemplate`) and explicit timeout values: ```java 1 import org.springframework.context.annotation.Bean; 2 import org.springframework.context.annotation.Configuration; 3 import org.springframework.http.client.SimpleClientHttpRequestFactory; 4 import org.springframework.security.oauth2.jwt.JwtDecoder; 5 import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; 6 import org.springframework.web.client.RestTemplate; 7 8 @Configuration 9 public class SecurityConfig { 10 11 @Bean 12 public JwtDecoder jwtDecoder() { 13 // Create a RestTemplate with custom timeouts 14 SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); 15 factory.setConnectTimeout(10000); // 10 seconds 16 factory.setReadTimeout(10000); // 10 seconds 17 18 RestTemplate restTemplate = new RestTemplate(factory); 19 20 // Use the custom RestTemplate for JWT validation 21 return NimbusJwtDecoder 22 .withIssuerLocation("https://auth.scalekit.com") 23 .restOperations(restTemplate) 24 .build(); 25 } 26 } ``` This gives you: * Full control over HTTP client configuration * Ability to add custom headers or interceptors * Environment-specific timeout tuning (development: 5000ms, production: 10000–15000ms) ## Verifying the fix [Section titled “Verifying the fix”](#verifying-the-fix) After applying the configuration: 1. **Restart your application** - Spring Security initializes the JWT decoder on startup 2. **Test authentication** - Make a request with a valid Scalekit JWT token 3. **Check logs** - You should see successful JWKS retrieval: ```plaintext 1 DEBUG o.s.security.oauth2.jwt.JwtDecoder - Retrieved JWKS from https://auth.scalekit.com/.well-known/jwks.json ``` If you still see timeout errors: * Verify network connectivity to `auth.scalekit.com` * Check firewall rules allowing outbound HTTPS * Increase timeout values if your network has high latency ## When to use standard Spring Security instead [Section titled “When to use standard Spring Security instead”](#when-to-use-standard-spring-security-instead) This cookbook addresses a specific Spring Boot 4.0+ timeout issue. For general JWT validation setup: * Follow the [Spring Security OAuth2 Resource Server documentation](https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html) * Use Scalekit’s standard Java SDK for token validation if not using Spring Security * Consider the default `issuer-uri` configuration if you’re not experiencing timeouts ## Related resources [Section titled “Related resources”](#related-resources) * [Spring Security OAuth2 Resource Server - JWT Timeouts](https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html#oauth2resourceserver-jwt-timeouts) * [Scalekit API reference](/apis/#tag/sessions) * [Spring Boot 4.0 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Release-Notes) --- # DOCUMENT BOUNDARY --- # Trace AgentKit tool calls in LangSmith > Add LangSmith observability to a LangChain agent that uses Scalekit AgentKit tools for Gmail, Slack, GitHub, and 200+ connectors. When you hand an LLM a set of tools — Gmail, Slack, GitHub, calendar — you need to see what happened. Which tool was called, with what arguments, what came back, and how long it took. Without that visibility, debugging a misbehaving agent means guessing. [LangSmith](https://smith.langchain.com) provides that visibility for LangChain agents. Scalekit AgentKit returns native LangChain `StructuredTool` objects, which means LangSmith traces them automatically — no wrapper code, no custom callbacks. Set two environment variables and every tool call shows up as a span in your trace. This recipe builds a Python agent that fetches Gmail messages through AgentKit and traces the entire run in LangSmith. The same pattern works with any of Scalekit’s 200+ connectors. ## What you are building [Section titled “What you are building”](#what-you-are-building) * **A LangChain agent** that uses Scalekit AgentKit tools to read Gmail. * **LangSmith tracing** that captures every LLM call, tool invocation, input/output, and latency as spans in a trace. * **A verification step** confirming traces appear in the LangSmith dashboard. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A Scalekit account at [app.scalekit.com](https://app.scalekit.com) with API credentials (**Settings → API Credentials**). * A **Gmail** connection configured under **Agent Auth → Connections**. See [Configure a connection](/agentkit/connections/). * A [LangSmith account](https://smith.langchain.com) and API key from **Settings → API Keys**. * An OpenAI API key, or a LiteLLM gateway URL with a virtual key. * **Python 3.10+** and **pip** or **uv**. 1. ## Install dependencies [Section titled “Install dependencies”](#install-dependencies) Terminal ```bash 1 pip install scalekit-sdk-python langchain-openai langsmith python-dotenv ``` `scalekit-sdk-python` includes the LangChain adapter. `langsmith` is the tracing client — importing it is enough for LangSmith to pick up traces when the environment variables are set. 2. ## Set environment variables [Section titled “Set environment variables”](#set-environment-variables) Create a `.env` file at the project root: .env ```bash 1 # Scalekit — from app.scalekit.com → Settings → API Credentials 2 # Threat: leaked credentials grant full API access to your Scalekit environment. 3 # Never commit this file to version control; add .env to .gitignore. 4 SCALEKIT_CLIENT_ID=skc_your_client_id 5 SCALEKIT_CLIENT_SECRET=skcs_your_client_secret 6 SCALEKIT_ENVIRONMENT_URL=https://your-subdomain.scalekit.dev 7 8 # LangSmith — from smith.langchain.com → Settings → API Keys 9 # Threat: exposed API key allows unauthorized trace reads and writes. 10 LANGCHAIN_TRACING_V2=true 11 LANGCHAIN_API_KEY=lsv2_your_langsmith_api_key 12 LANGCHAIN_PROJECT=scalekit-agentkit-traces 13 14 # LLM — OpenAI directly, or through a LiteLLM gateway 15 # Threat: exposed key allows unauthorized model usage billed to your account. 16 OPENAI_API_KEY=sk-your-openai-key ``` | Variable | Purpose | | ---------------------- | ------------------------------------------------------------ | | `LANGCHAIN_TRACING_V2` | Must be `true` to enable tracing | | `LANGCHAIN_API_KEY` | Your LangSmith API key (starts with `lsv2_`) | | `LANGCHAIN_PROJECT` | Project name in LangSmith — auto-created if it doesn’t exist | 3. ## Connect a user to Gmail [Section titled “Connect a user to Gmail”](#connect-a-user-to-gmail) Initialize the Scalekit client and ensure the user has an active Gmail connection: langsmith\_tracing.py ```python 1 import os 2 from dotenv import load_dotenv 3 4 load_dotenv() 5 6 import scalekit.client 7 8 scalekit_client = scalekit.client.ScalekitClient( 9 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 10 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 11 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 12 ) 13 actions = scalekit_client.actions 14 15 IDENTIFIER = "user_123" 16 17 response = actions.get_or_create_connected_account( 18 connection_name="gmail", 19 identifier=IDENTIFIER, 20 ) 21 if response.connected_account.status != "ACTIVE": 22 link = actions.get_authorization_link( 23 connection_name="gmail", 24 identifier=IDENTIFIER, 25 ) 26 print("Authorize Gmail:", link.link) 27 input("Press Enter after authorizing...") 28 else: 29 print(f"✅ Gmail connected for {IDENTIFIER}") ``` `get_or_create_connected_account` returns an existing session if one exists. If the user hasn’t authorized yet, `get_authorization_link` returns a URL the user opens in a browser. Scalekit handles the full OAuth exchange, validates the redirect callback, and stores the token. Your application never sees the `client_secret` used in the token exchange — Scalekit manages that server-side, which prevents credential leakage from frontend or agent code. 4. ## Load tools and run the agent [Section titled “Load tools and run the agent”](#load-tools-and-run-the-agent) `actions.langchain.get_tools()` returns a list of `StructuredTool` objects. Bind them to a model and run a standard tool-calling loop: langsmith\_tracing.py ```python 1 from langchain_core.messages import HumanMessage, ToolMessage 2 from langchain_openai import ChatOpenAI 3 4 tools = actions.langchain.get_tools( 5 identifier=IDENTIFIER, 6 connection_names=["gmail"], 7 ) 8 tool_map = {t.name: t for t in tools} 9 print(f"✅ Loaded {len(tools)} LangChain tools: {[t.name for t in tools[:5]]}") 10 11 llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) 12 messages = [HumanMessage("Fetch my last 3 unread emails and summarize them")] 13 14 while True: 15 response = llm.invoke(messages) 16 messages.append(response) 17 if not response.tool_calls: 18 print(response.content) 19 break 20 for tc in response.tool_calls: 21 print(f" 🔧 Tool call: {tc['name']}") 22 result = tool_map[tc["name"]].invoke(tc["args"]) 23 messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"])) ``` There is no tracing-specific code here. Because `LANGCHAIN_TRACING_V2=true` is set, LangSmith automatically instruments every `invoke` call — LLM requests, tool calls, and the full message chain. 5. ## Run and verify [Section titled “Run and verify”](#run-and-verify) Terminal ```bash 1 python langsmith_tracing.py ``` Expected output (the first line appears only if the account is already `ACTIVE`; on first run you will see the authorization URL instead): Terminal ```text ✅ Gmail connected for user_123 ✅ Loaded 8 LangChain tools: ['gmail_fetch_mails', 'gmail_send_mail', ...] 🔧 Tool call: gmail_fetch_mails Here are your 3 most recent unread emails: ... ``` Open [LangSmith](https://smith.langchain.com), select the **scalekit-agentkit-traces** project, and click the latest trace. You should see: * A **ChatOpenAI** span for the LLM call * A **gmail\_fetch\_mails** tool span showing the input arguments and the structured response from Gmail * Latency, token counts, and the full message chain ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Production notes [Section titled “Production notes”](#production-notes) **Token refresh is automatic.** Scalekit stores OAuth tokens per user per connector and refreshes them before expiry. Your agent code never handles refresh tokens directly. **Add multiple connectors.** Pass additional connection names to `get_tools()` to load tools from Gmail, Slack, GitHub, and others in a single call. LangSmith traces all of them identically. **Trace metadata.** Use LangSmith’s `@traceable` decorator or `with_config({"tags": [...]})` to add custom tags, metadata, or run names to your traces for filtering. **Cost tracking.** LangSmith captures token counts per LLM call. Combined with tool call traces, you get full-cost visibility per agent run. ## Next steps [Section titled “Next steps”](#next-steps) * [Configure more AgentKit connectors](/agentkit/connectors/) — add Slack, GitHub, Salesforce, and 200+ others alongside Gmail. * [Virtual MCP Servers](/agentkit/mcp/overview/) — serve AgentKit tools over MCP for use with any MCP-compatible client. * [LangSmith evaluation](https://docs.smith.langchain.com/evaluation) — score agent responses and tool usage across test datasets. * [LangSmith trace filtering](https://docs.smith.langchain.com/how_to_guides/tracing/filter_traces_in_application) — filter traces by metadata, tags, latency, or error status. ## Related resources [Section titled “Related resources”](#related-resources) | Topic | Link | | ------------------------- | --------------------------------------------------------------------------------- | | AgentKit overview | [Overview](/agentkit/overview/) | | LangChain framework guide | [LangChain](/agentkit/examples/langchain/) | | Connections | [Configure a connection](/agentkit/connections/) | | Connected accounts | [Manage connected accounts](/agentkit/connected-accounts/) | | Sample repository | [agent-auth-examples](https://github.com/scalekit-developers/agent-auth-examples) | | LangSmith docs | [docs.smith.langchain.com](https://docs.smith.langchain.com) | --- # DOCUMENT BOUNDARY --- # Triage a Gmail inbox with AgentKit and the LiteLLM gateway > Node.js inbox triage agent: classify Gmail threads, route to GitHub repos, draft issues and replies via LiteLLM, and approve before any side effects. Build an automated inbox triage agent that reads your Gmail, classifies each thread, routes it to the right GitHub repository, and notifies Slack — then waits for your approval before creating issues or sending replies. This Node.js sample uses **Scalekit AgentKit** for OAuth tool execution (Gmail, GitHub, Slack) and a **LiteLLM gateway** for model-per-stage routing. The only LiteLLM-specific config is `LITELLM_BASE_URL` and a virtual API key from the dashboard. The sample repository is **[litellm-agentkit-inbox-triage](https://github.com/scalekit-developers/litellm-agentkit-inbox-triage)** on GitHub. ## What you are building [Section titled “What you are building”](#what-you-are-building) * **Gmail ingestion** — Poll for new threads using AgentKit-executed Gmail tools. A SQLite cursor prevents duplicate processing. * **Model-per-stage routing** — Each stage (`classify`, `research`, `tiebreak`, `draft`) calls the LiteLLM gateway with a different model name. Stage-to-model assignments live in `routing.yaml` at the repo root. * **Deterministic GitHub routing** — Keyword rules in `routing.yaml` pick a target repository; an optional LLM tie-breaker resolves ties. * **Research loop** — A small tool-calling loop searches related GitHub issues through AgentKit. * **Slack notification** — Posts a summary with a link to the pending decision. * **Human approval** — A localhost dashboard lists proposals. **Approve** creates the GitHub issue, sends the Gmail reply, and updates Slack. **Reject** discards without side effects. ## Automated triage pipeline [Section titled “Automated triage pipeline”](#automated-triage-pipeline) New Gmail threads flow through AgentKit into a multi-stage LiteLLM pipeline, then land in SQLite as pending proposals. ## Human approval loop [Section titled “Human approval loop”](#human-approval-loop) Proposals wait in SQLite until you review them from the dashboard. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A Scalekit account at [app.scalekit.com](https://app.scalekit.com). * Ability to create **AgentKit connections** for **Gmail**, **GitHub**, and **Slack**. Connection **names** must match what you put in `.env` (see [Configure a connection](/agentkit/connections/)). * A **virtual LiteLLM API key** from the dashboard (**LLM Gateway**). A small spend cap of roughly two US dollars covers a handful of test threads. * **Node.js 24 or newer** and **npm**. * An **interactive terminal** — the sample prints authorization links and waits for Enter after each connector. This recipe does not cover headless CI. 1. ## Clone the sample [Section titled “Clone the sample”](#clone-the-sample) ```bash 1 git clone https://github.com/scalekit-developers/litellm-agentkit-inbox-triage.git 2 cd litellm-agentkit-inbox-triage ``` 2. ## Configure AgentKit connections [Section titled “Configure AgentKit connections”](#configure-agentkit-connections) 1. Open [app.scalekit.com](https://app.scalekit.com) → **AgentKit** → **Connections** → **Create Connection** for **Gmail**, **GitHub**, and **Slack**. 2. Copy each **Connection name** exactly as shown in the dashboard into `GMAIL_CONNECTION_NAME`, `GITHUB_CONNECTION_NAME`, and `SLACK_CONNECTION_NAME` in your `.env` file. 3. For **GitHub**, confirm the connection includes the **`repo`** OAuth scope (needed to create issues and search across repositories). Check **AgentKit → Connections → GitHub → Scopes** in the dashboard. See [Configure scopes](/agentkit/connections/#configure-scopes) and the [GitHub connector](/agentkit/connectors/github/). 4. For **Gmail** and **Slack**, follow the dashboard wizard. If your workspace restricts OAuth apps, see the connector docs: [Gmail](/agentkit/connectors/gmail/), [Slack](/agentkit/connectors/slack/). Dashboard only loads after all three connectors are active The sample calls `setupConnectors` **before** it binds the Express dashboard. You will **not** reach `http://localhost:3000` until Gmail, GitHub, and Slack each show **connector active** in the logs. 3. ## Create a LiteLLM virtual key and verify the gateway [Section titled “Create a LiteLLM virtual key and verify the gateway”](#create-a-litellm-virtual-key-and-verify-the-gateway) Open **LLM Gateway** in the Scalekit dashboard and create a **virtual API key** (optionally set a small budget cap for evaluation). Verify the gateway responds before continuing (load your `.env` first with `set -a && source .env && set +a`): ```bash 1 curl -H "Authorization: Bearer $LITELLM_API_KEY" \ 2 "$LITELLM_BASE_URL/v1/models" ``` Align `routing.yaml` → `models:` with the model IDs returned by that endpoint. 4. ## Configure and run the sample [Section titled “Configure and run the sample”](#configure-and-run-the-sample) Set these variables in `.env` before running: | Variable | Where to find it | | ------------------------ | ---------------------------------------------------- | | `SCALEKIT_ENV_URL` | Dashboard → **Settings** → Environment URL | | `SCALEKIT_CLIENT_ID` | Dashboard → **API Credentials** | | `SCALEKIT_CLIENT_SECRET` | Dashboard → **API Credentials** | | `GMAIL_CONNECTION_NAME` | Dashboard → **AgentKit → Connections** (exact label) | | `GITHUB_CONNECTION_NAME` | Same | | `SLACK_CONNECTION_NAME` | Same | | `LITELLM_BASE_URL` | Dashboard → **LLM Gateway** → Base URL | | `LITELLM_API_KEY` | Dashboard → **LLM Gateway** → virtual key value | ```bash 1 cp .env.example .env 2 # Fill in the variables above 3 4 npm install 5 npm run dev ``` Complete each printed **authorization URL** in the browser, then press **Enter** in the terminal after each connector. When you see **All connectors active** and **dashboard listening on `http://localhost:3000`**, send a test email to the connected Gmail account. Within roughly one poll interval (default **5 seconds**), a proposal appears in the dashboard. 5. ## Approve or reject [Section titled “Approve or reject”](#approve-or-reject) Open **`http://localhost:3000`**. Review the classification, routed repository, related issues, and drafts. **Approve** runs GitHub issue creation, sends the Gmail reply, and updates Slack. **Reject** leaves external systems unchanged. 6. ## Extend the sample [Section titled “Extend the sample”](#extend-the-sample) To add routing targets or swap models per stage, edit `routing.yaml` — each entry maps keyword rules to a GitHub repository and assigns a model name to each pipeline stage. To add connectors, follow the [AgentKit connections guide](/agentkit/connections/) and add the new connection name to `.env`. ## Related resources [Section titled “Related resources”](#related-resources) | Topic | Link | | ----------------------------- | --------------------------------------------------------------- | | AgentKit overview | [Overview](/agentkit/overview/) | | Connections | [Configure a connection](/agentkit/connections/) | | Authorization links | [Authorize a user](/agentkit/tools/authorize/) | | Connected accounts | [Manage connected accounts](/agentkit/connected-accounts/) | | LiteLLM virtual keys | [Virtual keys](https://docs.litellm.ai/docs/proxy/virtual_keys) | | LiteLLM model routing | [Router](https://docs.litellm.ai/docs/routing) | | LiteLLM OpenAI-compatible API | [Proxy usage](https://docs.litellm.ai/docs/proxy/user_keys) | ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) For deeper debugging patterns, see [Troubleshoot connection errors](/agentkit/authentication/troubleshooting/). --- # DOCUMENT BOUNDARY --- # Build a LiveKit voice agent with Scalekit AgentKit tools > Give a LiveKit voice agent secure access to Google Calendar and 200+ AgentKit connectors — no token ever reaches the browser or the LLM. A voice agent that answers “what’s on my calendar?” needs a Google OAuth token scoped to that specific user. [LiveKit](https://livekit.io) handles the realtime voice pipeline — speech-to-text, the LLM turn, text-to-speech, turn detection — but it has no built-in concept of per-user third-party credentials. Wire that up yourself and you’re building a token vault, a refresh cycle, and a way to keep both out of reach of the browser and the LLM, before you’ve written a single line of agent logic. Scalekit AgentKit removes that layer. It stores one OAuth session per connector per user and exposes a single `executeTool` call that runs any of 200+ connector actions on that user’s behalf. This cookbook connects a LiveKit Node.js agent to AgentKit directly — no MCP server, no separate auth service — and shows the one non-obvious part: getting the *identity* of the person talking to the agent from the browser to the worker process without ever exposing a credential. ## What you are building [Section titled “What you are building”](#what-you-are-building) * **A Next.js route** that dispatches a LiveKit agent into a room and mints a browser access token, carrying a Scalekit connection identifier through LiveKit’s dispatch `metadata` — the only channel between the two. * **A standalone LiveKit agent worker** (a separate Node process, not a Next.js route) that reads that identifier from `ctx.job.metadata` and calls `scalekit.actions.executeTool()` directly when the LLM decides to check the calendar. * **A pattern that generalizes**: swap `googlecalendar_list_events` for any AgentKit tool name and the identity-passing mechanism stays identical. The complete, working source (including the Next.js UI, both API routes, and the agent) is in [livekit-scalekit-voice-agent](https://github.com/scalekit-developers/livekit-scalekit-voice-agent). ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A [LiveKit Cloud](https://cloud.livekit.io) project — copy `LIVEKIT_URL`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET` from **Settings → Keys**. No `lk` CLI login is required; the app and the agent both read these three values from the environment. * A Scalekit account with **AgentKit** enabled and a `googlecalendar` connection that shows as **Active** for the identifier you’ll test with. See [Configure a connection](/agentkit/connections/). * **Node.js 20.11+** — the agent worker uses `import.meta.filename`, which older Node versions don’t have. 1. ## Install dependencies [Section titled “Install dependencies”](#install-dependencies) This is a two-process app: a Next.js frontend/API layer, and a standalone agent worker that runs as a separate `tsx` process. Terminal ```bash 1 npm install @scalekit-sdk/node livekit-server-sdk livekit-client @livekit/components-react @livekit/agents zod next react react-dom 2 npm install -D tsx typescript ``` `@livekit/agents` is the Node Agents SDK — it ships the `voice.AgentSession` pipeline, the `defineAgent`/`cli.runApp` worker entrypoint, and the `llm.tool()` helper for function tools. `@scalekit-sdk/node` is the same Scalekit client either side of this app uses to call AgentKit. 2. ## Set environment variables [Section titled “Set environment variables”](#set-environment-variables) Create `.env.local` at the project root: .env.local ```bash 1 # Scalekit — Settings → API Credentials in your Scalekit dashboard 2 SCALEKIT_ENV_URL=https://your-env.scalekit.com 3 SCALEKIT_CLIENT_ID=skc_your_client_id 4 SCALEKIT_CLIENT_SECRET=your_client_secret 5 6 # Demo-only stand-in for a real authenticated user's identifier 7 TEST_IDENTIFIER=user@example.com 8 9 # LiveKit Cloud — Settings → Keys 10 LIVEKIT_URL=wss://your-project.livekit.cloud 11 LIVEKIT_API_KEY=your_api_key 12 LIVEKIT_API_SECRET=your_api_secret ``` `TEST_IDENTIFIER` stands in for whatever your app uses to identify a logged-in user. In production this comes from the authenticated session, never from a static env var — see [Production notes](#production-notes). 3. ## Carry the identifier through LiveKit dispatch metadata [Section titled “Carry the identifier through LiveKit dispatch metadata”](#carry-the-identifier-through-livekit-dispatch-metadata) The Next.js route that starts a call is the only place that decides which Scalekit identity the agent runs as. It never sends a token — just the identifier — inside LiveKit’s own `metadata` field on the agent dispatch: app/api/livekit/start/route.ts ```typescript 1 import { randomUUID } from 'node:crypto'; 2 import { NextResponse } from 'next/server'; 3 import { AccessToken, AgentDispatchClient } from 'livekit-server-sdk'; 4 5 const AGENT_NAME = 'scalekit-voice-agent'; 6 7 export async function POST(req: Request) { 8 const livekitUrl = process.env.LIVEKIT_URL!; 9 const apiKey = process.env.LIVEKIT_API_KEY!; 10 const apiSecret = process.env.LIVEKIT_API_SECRET!; 11 12 const { identifier } = await req.json(); 13 const roomName = `voice-${randomUUID()}`; 14 const metadata = JSON.stringify({ scalekitConnectionId: identifier }); 15 16 const dispatchClient = new AgentDispatchClient(livekitUrl, apiKey, apiSecret); 17 await dispatchClient.createDispatch(roomName, AGENT_NAME, { metadata }); 18 19 const at = new AccessToken(apiKey, apiSecret, { identity: `user-${randomUUID()}` }); 20 at.addGrant({ roomJoin: true, room: roomName }); 21 const token = await at.toJwt(); 22 23 return NextResponse.json({ roomName, token, url: livekitUrl, identifier }); 24 } ``` `createDispatch(roomName, agentName, { metadata })` tells LiveKit’s cloud infrastructure to route this room to a worker registered under `agentName` — you’ll register the same string in the next step. `metadata` is a plain JSON string; LiveKit stores it and hands it to the worker’s job context untouched. The browser only ever receives `token` (a room-join JWT) and `roomName` — never a Scalekit credential. This is the entire security boundary Everything downstream trusts that `identifier` came from your authenticated backend, not from user input. In this demo it falls back to `TEST_IDENTIFIER` for convenience — in production, derive it from the session on the server, never from a request body field a client could set directly. 4. ## Read the identifier and call the tool directly [Section titled “Read the identifier and call the tool directly”](#read-the-identifier-and-call-the-tool-directly) The agent worker is a separate file, run as its own process — not a Next.js route. It parses the same metadata shape the dispatch call sent, then wires a Scalekit-backed function tool: agent/src/agent.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { cli, defineAgent, llm, ServerOptions, voice, type JobContext } from '@livekit/agents'; 3 import { z } from 'zod'; 4 5 const scalekit = new ScalekitClient( 6 process.env.SCALEKIT_ENV_URL!, 7 process.env.SCALEKIT_CLIENT_ID!, 8 process.env.SCALEKIT_CLIENT_SECRET!, 9 ); 10 11 const entry = async (ctx: JobContext): Promise => { 12 await ctx.connect(); 13 14 const metadata = JSON.parse(ctx.job.metadata || '{}') as { scalekitConnectionId?: string }; 15 const identifier = metadata.scalekitConnectionId || process.env.TEST_IDENTIFIER || 'demo-connection'; 16 17 const googlecalendar_list_events = llm.tool({ 18 description: "List events from the user's Google Calendar. Use this when the user asks about their schedule.", 19 parameters: z.object({ 20 calendar_id: z.string().optional().describe("Defaults to 'primary'."), 21 }), 22 execute: async ({ calendar_id }) => { 23 const result = await scalekit.actions.executeTool({ 24 connector: 'googlecalendar', 25 identifier, 26 toolName: 'googlecalendar_list_events', 27 toolInput: { calendar_id: calendar_id ?? 'primary' }, 28 }); 29 return result.data ?? result; 30 }, 31 }); 32 33 const agent = new voice.Agent({ 34 instructions: "You are a helpful voice assistant. Check the user's calendar when asked.", 35 tools: { googlecalendar_list_events }, 36 }); 37 38 const session = new voice.AgentSession({ 39 llm: 'openai/gpt-4o-mini', 40 stt: 'assemblyai/universal-streaming', 41 tts: 'cartesia/sonic-2', 42 }); 43 44 await session.start({ agent, room: ctx.room }); 45 await session.generateReply({ instructions: 'Greet the user and offer to help with their calendar.' }); 46 }; 47 48 export default defineAgent({ entry }); 49 50 cli.runApp(new ServerOptions({ agent: import.meta.filename, agentName: 'scalekit-voice-agent' })); ``` Three things worth naming explicitly: * **`llm.tool()`’s object key is the tool’s name** — there’s no `name` field inside the call. The LLM sees the tool as `googlecalendar_list_events` because that’s the key in the `tools: { googlecalendar_list_events }` map. * **`voice.Agent` is a plain constructor** — `new voice.Agent({ instructions, tools })`. There’s no static factory method. * **The three model strings are [LiveKit Inference](https://docs.livekit.io/agents/) identifiers**, not your own API keys. They route STT/LLM/TTS through LiveKit Cloud’s gateway, billed to your LiveKit project — no separate OpenAI, AssemblyAI, or Cartesia account needed to get this running. `agentName: 'scalekit-voice-agent'` must match the string `AgentDispatchClient.createDispatch()` used in step 3 exactly. That’s the only thing connecting the two processes — get it wrong and the dispatch succeeds, a room gets created, and the agent simply never joins it. 5. ## Run both processes [Section titled “Run both processes”](#run-both-processes) Terminal 1 — Next.js app ```bash 1 npm run dev ``` Terminal 2 — agent worker ```bash 1 npx tsx watch --env-file=.env.local agent/src/agent.ts dev ``` `--env-file` matters here: Next.js loads `.env.local` automatically, but a plain `tsx` process doesn’t unless you tell it to. ## Testing [Section titled “Testing”](#testing) Confirm the identity actually reaches the agent before wiring up a browser. Hit the dispatch route directly: Terminal ```bash 1 curl -X POST http://localhost:3000/api/livekit/start \ 2 -H 'Content-Type: application/json' \ 3 -d '{"identifier":"user@example.com"}' ``` The agent worker’s terminal should log the same identifier within a couple of seconds: Terminal 2 output ```text [scalekit-voice-agent] job=AJ_giyT9fjSxPg8 room=voice-2eb7cc3d-... identifier=user@example.com ``` If that line doesn’t appear, the agent never received the dispatch — see [Common mistakes](#common-mistakes) below before checking anything else. Once it does, open your frontend, click **Start**, and ask “what’s on my calendar today?” — the agent should call `executeTool`, get back real calendar data, and speak a summary. ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Production notes [Section titled “Production notes”](#production-notes) **No token ever reaches the browser or the LLM.** The Next.js route returns a room-join JWT (scoped to one room) and the identifier string — never a Scalekit credential. The agent worker is the only process that ever constructs a `ScalekitClient`, and `executeTool()`’s result — plain calendar data — is the only thing that reaches the LLM. **MCP isn’t available in this SDK yet.** As of `@livekit/agents` 1.4.11, there is no MCP toolset for the Node Agents SDK — direct `executeTool()` calls, as shown above, are the only path. Check the installed version’s type declarations before assuming otherwise; this changes over time. **Derive the identifier from a real session, not a static env var.** `TEST_IDENTIFIER` is a demo convenience. In production, read it from your authenticated user’s session on the server that handles the dispatch request — never from a client-supplied field. **Add more tools by changing one string.** The `connector`/`toolName` pair in `executeTool()` is the only connector-specific part of this code. Swap `googlecalendar_list_events` for any of [200+ AgentKit connectors](/agentkit/connectors/) and the identity-passing mechanism is unchanged. ## Next steps [Section titled “Next steps”](#next-steps) * [Configure more connectors](/agentkit/connectors/) — extend beyond Google Calendar to Gmail, Slack, or GitHub. * [Connected accounts](/agentkit/connected-accounts/) — check connection status and revoke access programmatically. * [AgentKit quickstart](/agentkit/quickstart/) — connect your first user in under five minutes. * [LiveKit Agents docs](https://docs.livekit.io/agents/) — turn detection, interruption handling, and telephony/SIP. ## Related resources [Section titled “Related resources”](#related-resources) | Topic | Link | | ------------------- | --------------------------------------------------------------------------------------------------- | | AgentKit overview | [Overview](/agentkit/overview/) | | All connectors | [Connectors](/agentkit/connectors/) | | Connected accounts | [Manage connected accounts](/agentkit/connected-accounts/) | | Sample repository | [livekit-scalekit-voice-agent](https://github.com/scalekit-developers/livekit-scalekit-voice-agent) | | LiveKit Agents docs | [docs.livekit.io/agents](https://docs.livekit.io/agents/) | --- # DOCUMENT BOUNDARY --- # M2M JWT verification with JWKS and OAuth scopes > How JSON Web Key Sets work with Scalekit, how to use the /keys endpoint to verify machine-to-machine tokens, and how OAuth scopes map to JWT claims for authorization. When you add OAuth 2.0 client credentials for your APIs, callers receive **JWT access tokens**. Before you trust any claim, you must **verify the signature** using Scalekit’s public keys (**JWKS**). After verification, you **authorize** the request—often by checking **OAuth scopes** carried in the token. This cookbook explains how JWKS and scopes fit together for Scalekit M2M flows: where keys live, how verification works at a high level, how scopes are defined and stored, and how to enforce them in your service. ## Why JWKS and scopes belong in one place [Section titled “Why JWKS and scopes belong in one place”](#why-jwks-and-scopes-belong-in-one-place) * **JWKS answers “is this token real?”** — You use the key identified by `kid` in the JWT header to validate the signature (typically **RS256**). * **Scopes answer “what may this client do?”** — After the token is valid, you inspect the `scopes` claim (and your routing rules) to allow or deny the operation. Skipping either step breaks your security model: verified-but-overpowered clients, or unverified tokens. ## JWKS and Scalekit keys [Section titled “JWKS and Scalekit keys”](#jwks-and-scalekit-keys) A **JSON Web Key Set (JWKS)** is JSON that lists one or more **JWKs**—public key material identified by a `kid` (key ID). Scalekit puts the matching `kid` in the JWT header so your validator can pick the right key without baking certificates into your app. Each environment publishes signing keys at: ```http 1 GET https:///keys ``` Use the same base URL as `/oauth/token` (for example `https://your-app.scalekit.dev`). Example response shape: Example JWKS document ```json 1 { 2 "keys": [ 3 { 4 "use": "sig", 5 "kty": "RSA", 6 "kid": "snk_58327480989122566", 7 "alg": "RS256", 8 "n": "…", 9 "e": "AQAB" 10 } 11 ] 12 } ``` For access tokens, use the key where `use` is `sig` and `alg` is `RS256`. ## Verify an access token [Section titled “Verify an access token”](#verify-an-access-token) At implementation time, your API typically: 1. **Extracts** the bearer token from `Authorization: Bearer `. 2. **Decodes** the JWT header (base64url, first segment) and reads `kid` and `alg`. Do not trust the payload until the signature checks out. 3. **Resolves the signing key** — fetch `https:///keys`, or use a JWKS client (for example `jwks-rsa` in Node.js) with **caching** and refresh when you see an unknown `kid`. 4. **Verifies** the signature with your JWT library (RS256 for Scalekit access tokens). 5. **Validates claims** such as `exp`, `iss` (your environment URL), and `aud` if your API relies on audience restrictions. 6. **Authorizes** the operation using application claims—especially **`scopes`** (covered in the next section). ### Operational practices [Section titled “Operational practices”](#operational-practices) * **Cache JWKS** responses; refetch when verification fails with an unknown `kid` (key rotation). * **Fail closed** on bad signature, wrong issuer, or expired token (`401`; use `403` when the token is valid but not allowed). * **Never** skip signature verification based on the payload alone. ## OAuth scopes for machine clients [Section titled “OAuth scopes for machine clients”](#oauth-scopes-for-machine-clients) **Scopes** are permission names you attach to an OAuth client. In M2M flows they describe *what* a client may do—separate from *who* it is (`client_id` / `sub`). ### Why scopes matter [Section titled “Why scopes matter”](#why-scopes-matter) Without scopes, any valid client could hit any endpoint. Scopes let you apply **least privilege**, **document** what each integration is for, and **enforce** rules in your API by reading the `scopes` array on the JWT. ### How scopes work in Scalekit M2M [Section titled “How scopes work in Scalekit M2M”](#how-scopes-work-in-scalekit-m2m) 1. When you **register an API client** for an organization, you pass a `scopes` array (REST or SDKs). 2. Scalekit stores those scopes and includes them on issued access tokens. 3. Your API **verifies the JWT** (steps above), then checks that `scopes` includes what the route requires. Use a consistent naming pattern such as `resource:action` (for example `deployments:read`, `deployments:write`). ### Register scopes on the client [Section titled “Register scopes on the client”](#register-scopes-on-the-client) Scopes are set at **client creation** (and when you update the client via the API). Example: scopes on create client (illustrative) ```json 1 "scopes": [ 2 "deploy:applications", 3 "read:deployments" 4 ] ``` The same values appear on the client record and in issued tokens. ### Validate scopes on your API [Section titled “Validate scopes on your API”](#validate-scopes-on-your-api) After the token is verified: * **Read `scopes`** from the payload, for example: scopes in JWT payload (example) ```json 1 "scopes": [ 2 "deploy:applications", 3 "read:deployments" 4 ] ``` * **Compare** what the token grants to what the route allows (for example require `deploy:applications` on `POST /deploy`); return `403` if a required scope is missing. * **Use SDK helpers** where they fit your stack to combine signature and scope checks (see the [quickstart](/authenticate/m2m/api-auth-quickstart/)). ## Related [Section titled “Related”](#related) * [Add OAuth 2.0 to your APIs](/authenticate/m2m/api-auth-quickstart/) — client registration, tokens, examples * [API keys](/authenticate/m2m/api-keys/) — long-lived keys; patterns may differ from OAuth client credentials * [Authenticate customer apps](/guides/m2m/api-auth-m2m-clients/) — customer-facing API auth and JWKS examples --- # DOCUMENT BOUNDARY --- # Build a Mastra agent with Scalekit AgentKit tools > Give a Mastra agent access to Gmail and 200+ connectors through Scalekit AgentKit — zero manual OAuth handling. A [Mastra](https://mastra.ai) agent that reads emails needs a Gmail OAuth token. An agent that also posts to Slack needs a second token. Each tool means another OAuth flow, another token store, another refresh cycle. Before you write any agent logic, you are already maintaining parallel credential pipelines. Scalekit AgentKit eliminates that overhead. It stores one OAuth session per connector per user, handles token refresh automatically, and gives your agent a single API surface for 200+ connectors. This recipe shows how to discover AgentKit tools at runtime, wrap them as native Mastra tools, and run them through a Mastra agent — all in TypeScript, with no Python backend. ## What you are building [Section titled “What you are building”](#what-you-are-building) * **A Mastra agent** that fetches Gmail messages through Scalekit AgentKit. * **Dynamic tool discovery** — the agent discovers available tools at runtime from Scalekit, instead of hardcoding tool definitions. * **Magic link authorization** — if the user has not connected their Gmail account, the agent generates an authorization URL. * **A pattern you can extend** to any of Scalekit’s [200+ connectors](/agentkit/connectors/) by changing a single string. The complete source is available in the [mastra-agentkit-example](https://github.com/scalekit-developers/mastra-agentkit-example) repository. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A Scalekit account at [app.scalekit.com](https://app.scalekit.com) with API credentials (**Settings → API Credentials**). * A **Gmail** connection configured under **AgentKit → Connections**. See [Configure a connection](/agentkit/connections/). * An OpenAI API key. * **Node.js 18+** and **pnpm** (or npm). 1. ## Install dependencies [Section titled “Install dependencies”](#install-dependencies) Terminal ```bash 1 pnpm add @mastra/core @scalekit-sdk/node @ai-sdk/openai zod dotenv 2 pnpm add -D tsx typescript @types/node ``` `@mastra/core` provides the `Agent` and `createTool` primitives. `@scalekit-sdk/node` handles authentication, tool discovery, and tool execution against the Scalekit API. `@ai-sdk/openai` connects the agent to GPT-4o. 2. ## Set environment variables [Section titled “Set environment variables”](#set-environment-variables) Create a `.env` file at the project root: .env ```bash 1 # Scalekit — from app.scalekit.com → Settings → API Credentials 2 # Threat: leaked credentials grant full API access to your Scalekit environment. 3 # Never commit this file to version control; add .env to .gitignore. 4 SCALEKIT_ENV_URL=https://your-env.scalekit.dev 5 SCALEKIT_CLIENT_ID=skc_your_client_id 6 SCALEKIT_CLIENT_SECRET=your_client_secret 7 8 # OpenAI 9 # Threat: exposed key allows unauthorized model usage billed to your account. 10 OPENAI_API_KEY=sk-your-openai-key 11 12 # User and connection — replace with values from your application 13 USER_IDENTIFIER=user_123 14 CONNECTION_NAME=gmail ``` | Variable | Purpose | | ------------------------ | --------------------------------------------------------- | | `SCALEKIT_ENV_URL` | Your Scalekit environment URL (starts with `https://`) | | `SCALEKIT_CLIENT_ID` | Client ID from API Credentials (starts with `skc_`) | | `SCALEKIT_CLIENT_SECRET` | Client secret from API Credentials | | `OPENAI_API_KEY` | OpenAI API key for GPT-4o | | `USER_IDENTIFIER` | A unique identifier for the end user in your application | | `CONNECTION_NAME` | The connection name configured in your Scalekit dashboard | 3. ## Initialize Scalekit and ensure the user is connected [Section titled “Initialize Scalekit and ensure the user is connected”](#initialize-scalekit-and-ensure-the-user-is-connected) Create `src/index.ts`. Start by initializing the Scalekit client and checking whether the user has an active Gmail connection: src/index.ts ```typescript 1 import { Agent } from '@mastra/core/agent'; 2 import { createTool } from '@mastra/core/tools'; 3 import { openai } from '@ai-sdk/openai'; 4 import { ScalekitClient } from '@scalekit-sdk/node'; 5 import { z } from 'zod'; 6 import 'dotenv/config'; 7 8 const IDENTIFIER = process.env.USER_IDENTIFIER || 'user_123'; 9 const CONNECTION = process.env.CONNECTION_NAME || 'gmail'; 10 11 const scalekit = new ScalekitClient( 12 process.env.SCALEKIT_ENV_URL!, 13 process.env.SCALEKIT_CLIENT_ID!, 14 process.env.SCALEKIT_CLIENT_SECRET!, 15 ); 16 17 const { connectedAccount } = await scalekit.actions.getOrCreateConnectedAccount({ 18 connectionName: CONNECTION, 19 identifier: IDENTIFIER, 20 }); 21 22 if (connectedAccount?.status?.toString() !== '1') { 23 const { link } = await scalekit.actions.getAuthorizationLink({ 24 connectionName: CONNECTION, 25 identifier: IDENTIFIER, 26 }); 27 console.log(`\n[${CONNECTION}] Authorization required.`); 28 console.log(`Open this link:\n\n ${link}\n`); 29 console.log('Press Enter once you have completed the OAuth flow...'); 30 await new Promise((resolve) => { 31 process.stdin.resume(); 32 process.stdin.once('data', () => { process.stdin.pause(); resolve(); }); 33 }); 34 } ``` `getOrCreateConnectedAccount` returns an existing session if one exists or creates a pending one. If the account is not active (status `1`), `getAuthorizationLink` returns a URL you open in a browser. Scalekit handles the full OAuth exchange — your application never sees the provider’s client secret. 4. ## Discover tools from Scalekit [Section titled “Discover tools from Scalekit”](#discover-tools-from-scalekit) Once the user is connected, list the tools available for their account: src/index.ts (continued) ```typescript 1 const toolsResponse = await scalekit.tools.listTools({ 2 filter: { connector: CONNECTION, identifier: IDENTIFIER }, 3 pageSize: 50, 4 }); 5 6 const scalekitTools = toolsResponse.tools; 7 console.log( 8 `Discovered ${scalekitTools.length} tools: ` + 9 scalekitTools.map((t) => (t.definition as any)?.name).join(', ') 10 ); ``` `listTools` returns tool definitions that include a `name`, `description`, and `input_schema` (a JSON Schema object). The `filter` parameter scopes results to the connector and user — the agent only sees tools the user has authorized. 5. ## Convert Scalekit tools to Mastra tools [Section titled “Convert Scalekit tools to Mastra tools”](#convert-scalekit-tools-to-mastra-tools) Mastra agents accept tools created with `createTool`. Each Scalekit tool needs to be wrapped: src/index.ts (continued) ```typescript 1 const mastraTools: Record> = {}; 2 3 for (const tool of scalekitTools) { 4 const def = tool.definition as Record | undefined; 5 if (!def?.name) continue; 6 7 const toolName: string = def.name; 8 const description: string = def.description || toolName; 9 10 // Use a permissive Zod schema — Scalekit validates inputs server-side. 11 const inputSchema = z.object({}).passthrough(); 12 13 mastraTools[toolName] = createTool({ 14 id: toolName, 15 description, 16 inputSchema, 17 execute: async ({ context }) => { 18 const result = await scalekit.tools.executeTool({ 19 toolName, 20 identifier: IDENTIFIER, 21 params: context as Record, 22 }); 23 return result; 24 }, 25 }); 26 } ``` The `inputSchema` uses `z.object({}).passthrough()` — a permissive schema that lets the LLM pass any parameters through. Scalekit validates inputs server-side, so client-side validation is optional. If you want stricter types, convert the JSON Schema from `def.input_schema` into a typed Zod schema. The `execute` function calls `scalekit.tools.executeTool()`, which sends the tool call to Scalekit. Scalekit injects the user’s OAuth token, calls the third-party API, and returns the structured response. 6. ## Build and run the agent [Section titled “Build and run the agent”](#build-and-run-the-agent) Create the Mastra agent with the discovered tools and run it: src/index.ts (continued) ```typescript 1 const agent = new Agent({ 2 name: 'gmail-assistant', 3 instructions: 4 'You are a helpful Gmail assistant. Use the available tools to fulfill requests. ' + 5 'Always confirm what you did after completing an action.', 6 model: openai('gpt-4o'), 7 tools: mastraTools, 8 }); 9 10 const prompt = process.argv[2] || 'Fetch my last 5 unread emails and summarize them.'; 11 console.log(`\nPrompt: ${prompt}\n`); 12 13 const result = await agent.generate(prompt); 14 console.log(result.text); ``` Add a start script to `package.json`: package.json (scripts section) ```json 1 { 2 "scripts": { 3 "start": "tsx src/index.ts" 4 } 5 } ``` 7. ## Run and verify [Section titled “Run and verify”](#run-and-verify) Terminal ```bash 1 pnpm start ``` On the first run, if the user hasn’t authorized Gmail, you see the authorization flow: Terminal ```text [gmail] Authorization required. Open this link: https://auth.scalekit.dev/connect/... Press Enter once you have completed the OAuth flow... ``` After authorization (or on subsequent runs), the agent runs: Terminal ```text Connected account for user_123 is active. Discovered 8 tools: gmail_fetch_mails, gmail_send_mail, gmail_search_mails, ... Created 8 Mastra tools. Prompt: Fetch my last 5 unread emails and summarize them. Here are your 5 most recent unread emails: 1. "Q1 roadmap feedback needed" — Sarah Chen (1h ago) Requesting feedback on the product roadmap by Friday. 2. "Deploy failed: production" — GitHub Actions (2h ago) CI pipeline failed on the main branch, test suite timeout. 3. "New PR review requested" — Lin Feng (3h ago) Review requested on PR #412: refactor auth middleware. ... ``` You can also pass a custom prompt: Terminal ```bash 1 pnpm start "Search for emails from GitHub and list the subjects" ``` ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Production notes [Section titled “Production notes”](#production-notes) **Token refresh is automatic.** Scalekit stores OAuth tokens per user per connector and refreshes them before expiry. Your agent code never handles refresh tokens directly. **Scope tools per user.** The `identifier` parameter in `listTools` and `executeTool` ensures each user only accesses their own connected accounts. Never share an identifier across users. **Add more connectors.** Change `CONNECTION_NAME` to `slack`, `notion`, `googlecalendar`, or any of the [200+ supported connectors](/agentkit/connectors/). The code is identical — only the connection name changes. **Error handling in production.** Wrap `executeTool` calls in try/catch to handle network errors and expired connections gracefully. Return a clear message to the user when a tool call fails instead of letting the agent retry silently. **MCP alternative.** If you prefer Mastra’s built-in MCP client over manual tool wrapping, see the [Mastra MCP example](/agentkit/examples/mastra/). That approach requires a per-user MCP URL generated from the Python SDK. ## Next steps [Section titled “Next steps”](#next-steps) * [Configure more connectors](/agentkit/connectors/) — add Slack, GitHub, Salesforce, and others alongside Gmail. * [Mastra MCP integration](/agentkit/examples/mastra/) — use Mastra’s native MCP client with a Scalekit MCP URL. * [AgentKit quickstart](/agentkit/quickstart/) — connect your first user in under five minutes. * [Connected accounts](/agentkit/connected-accounts/) — manage user connections, check status, and revoke access programmatically. ## Related resources [Section titled “Related resources”](#related-resources) | Topic | Link | | ------------------ | ----------------------------------------------------------------------------------------- | | AgentKit overview | [Overview](/agentkit/overview/) | | All connectors | [Connectors](/agentkit/connectors/) | | Connected accounts | [Manage connected accounts](/agentkit/connected-accounts/) | | Mastra MCP example | [Mastra](/agentkit/examples/mastra/) | | Sample repository | [mastra-agentkit-example](https://github.com/scalekit-developers/mastra-agentkit-example) | | Mastra docs | [mastra.ai/docs](https://mastra.ai/docs) | --- # DOCUMENT BOUNDARY --- # Migrate from Auth0 to Scalekit > Move users, organizations, and enterprise SSO off Auth0 to Scalekit Full Stack Auth with a safe, incremental cutover. Migrating a B2B app off Auth0 is risky because three things move at once: user records, the organization or tenant structure, and enterprise SSO connections. Do it in one big switch and you risk locking customers out. This recipe moves each piece to [Scalekit Full Stack Auth](/authenticate/fsa/quickstart/) in a safe, reversible order, then cuts traffic over behind a feature flag. The approach avoids re-hashing passwords. Instead of copying credentials, you point your app at Scalekit’s hosted login and let users re-authenticate through SSO, social login, or passwordless on their next visit. This is the recommended path for B2B products, where most enterprise users already sign in through an identity provider rather than a password. ## What you build [Section titled “What you build”](#what-you-build) * A field mapping from Auth0 users, organizations, and connections to Scalekit * A one-time import script that recreates organizations and users with `external_id` back-references * Enterprise SSO connections rebuilt in Scalekit for each customer that used them * An incremental cutover behind a feature flag, with a rollback path ## Who needs this [Section titled “Who needs this”](#who-needs-this) This recipe is for you if: * You authenticate a B2B or multi-tenant app on Auth0 today, using Auth0 Organizations or per-tenant connections. * You want Scalekit to own hosted login, sessions, enterprise SSO, and SCIM going forward. * You can run a short backfill script and toggle a feature flag in your app. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * An Auth0 tenant with a Machine-to-Machine application authorized for the Auth0 Management API. * A Scalekit account with API credentials from the dashboard. See [Set up Scalekit](/authenticate/fsa/quickstart/). * The Scalekit SDK installed in your backend. ## How Auth0 concepts map to Scalekit [Section titled “How Auth0 concepts map to Scalekit”](#how-auth0-concepts-map-to-scalekit) Start from the data model. Every later step follows this mapping. | Auth0 concept | Scalekit concept | Notes | | ------------------------------------ | -------------------- | -------------------------------------------------------------------------------------- | | Organization | Organization | Store the Auth0 `org_id` as the Scalekit `external_id`. | | User | User + membership | Users belong to an organization through a membership that carries roles. | | `user_id` (for example `auth0\|abc`) | User `external_id` | Preserves lookups between systems during cutover. | | Enterprise connection (SAML, OIDC) | SSO connection | Recreated per organization in Scalekit; secrets are not exportable from Auth0. | | Roles and permissions | Roles | Recreate roles in Scalekit, then attach them to memberships on import. | | Database (password) users | Hosted login re-auth | Users re-verify through SSO, social, or passwordless. See the following password note. | ## Migrate the data [Section titled “Migrate the data”](#migrate-the-data) 1. ## Export your Auth0 data [Section titled “Export your Auth0 data”](#export-your-auth0-data) Pull three datasets from Auth0 using the [Management API](https://auth0.com/docs/api/management/v2) or the [User Import / Export extension](https://auth0.com/docs/customize/extensions/user-import-export-extension). Create a [bulk user export job](https://auth0.com/docs/manage-users/user-migration/bulk-user-exports) to get every user as newline-delimited JSON: Export Auth0 users ```bash 1 # Security: pass the Management API token from an environment variable, never inline it. 2 curl "https://YOUR_AUTH0_DOMAIN/api/v2/jobs/users-exports" \ 3 --request POST \ 4 --header "Authorization: Bearer $AUTH0_MGMT_TOKEN" \ 5 --header 'Content-Type: application/json' \ 6 --data '{ 7 "format": "json", 8 "fields": [ 9 { "name": "user_id" }, 10 { "name": "email" }, 11 { "name": "email_verified" }, 12 { "name": "given_name" }, 13 { "name": "family_name" } 14 ] 15 }' ``` Poll `GET /api/v2/jobs/{job_id}` until the job reports `completed`, then download the file it returns. Then export [organizations](https://auth0.com/docs/manage-users/organizations) and their members: Export Auth0 organizations and members ```bash 1 curl "https://YOUR_AUTH0_DOMAIN/api/v2/organizations" \ 2 --header "Authorization: Bearer $AUTH0_MGMT_TOKEN" 3 4 # For each organization id returned above: 5 curl "https://YOUR_AUTH0_DOMAIN/api/v2/organizations/{org_id}/members" \ 6 --header "Authorization: Bearer $AUTH0_MGMT_TOKEN" ``` Finally, list the enterprise connections you rebuild in Scalekit. Record the identity provider, metadata URL, and which organizations use each one. Connection secrets stay in the identity provider and are not exportable. List Auth0 enterprise connections ```bash 1 curl "https://YOUR_AUTH0_DOMAIN/api/v2/connections?strategy=samlp" \ 2 --header "Authorization: Bearer $AUTH0_MGMT_TOKEN" ``` 2. ## Install the Scalekit SDK [Section titled “Install the Scalekit SDK”](#install-the-scalekit-sdk) Add the SDK to the backend that runs your import script. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` 3. ## Import organizations first [Section titled “Import organizations first”](#import-organizations-first) Create each Auth0 organization in Scalekit and set `external_id` to the Auth0 `org_id`. This back-reference lets you attach users to the right organization and reconcile records during cutover. * Node.js import-organizations.js ```javascript 1 // organizations: rows read from your Auth0 organizations export 2 for (const org of organizations) { 3 const result = await scalekit.organization.createOrganization(org.display_name, { 4 externalId: org.id, // Auth0 org_id, preserved for lookups 5 metadata: { source: 'auth0' }, 6 }); 7 console.log(`Created organization: ${result.id}`); 8 } ``` * Python import\_organizations.py ```python 1 from scalekit.v1.organizations.organizations_pb2 import CreateOrganization 2 3 # organizations: rows read from your Auth0 organizations export 4 for org in organizations: 5 result = scalekit_client.organization.create_organization( 6 CreateOrganization( 7 display_name=org["display_name"], 8 external_id=org["id"], # Auth0 org_id, preserved for lookups 9 metadata={"source": "auth0"}, 10 ) 11 ) 12 print(f"Created organization: {result.id}") ``` * Go import\_organizations.go ```go 1 // organizations: rows read from your Auth0 organizations export 2 for _, org := range organizations { 3 result, err := scalekitClient.Organization.CreateOrganization( 4 ctx, 5 org.DisplayName, 6 scalekit.CreateOrganizationOptions{ 7 ExternalID: org.ID, // Auth0 org_id, preserved for lookups 8 Metadata: map[string]interface{}{"source": "auth0"}, 9 }, 10 ) 11 if err != nil { 12 log.Fatal(err) 13 } 14 fmt.Printf("Created organization: %s\n", result.ID) 15 } ``` * Java ImportOrganizations.java ```java 1 // organizations: rows read from your Auth0 organizations export 2 for (Map org : organizations) { 3 CreateOrganization createOrganization = CreateOrganization.newBuilder() 4 .setDisplayName((String) org.get("display_name")) 5 .setExternalId((String) org.get("id")) // Auth0 org_id, preserved for lookups 6 .putMetadata("source", "auth0") 7 .build(); 8 9 Organization result = scalekitClient.organizations().create(createOrganization); 10 System.out.println("Created organization: " + result.getId()); 11 } ``` 4. ## Import users into their organizations [Section titled “Import users into their organizations”](#import-users-into-their-organizations) Create each user inside the organization it belongs to, and set the user `external_id` to the Auth0 `user_id`. Attach roles through the membership so access control works on the first login. Set `sendInvitationEmail` to `false` to skip invite emails during a bulk backfill. Scalekit marks the membership `active` and treats the email as verified. * Node.js import-users.js ```javascript 1 const { user } = await scalekit.user.createUserAndMembership(organizationId, { 2 email: row.email, 3 externalId: row.user_id, // Auth0 user_id, e.g. "auth0|abc123" 4 sendInvitationEmail: false, 5 userProfile: { 6 firstName: row.given_name, 7 lastName: row.family_name, 8 }, 9 metadata: { roles: row.roles?.join(',') ?? '' }, 10 }); 11 console.log(`Created user: ${user.id}`); ``` * Python import\_users.py ```python 1 from scalekit.v1.users.users_pb2 import CreateUser 2 from scalekit.v1.commons.commons_pb2 import UserProfile 3 4 user_msg = CreateUser( 5 email=row["email"], 6 external_id=row["user_id"], # Auth0 user_id, e.g. "auth0|abc123" 7 user_profile=UserProfile( 8 first_name=row["given_name"], 9 last_name=row["family_name"], 10 ), 11 ) 12 13 create_resp, _ = scalekit_client.user.create_user_and_membership( 14 organization_id, user_msg 15 ) 16 print(f"Created user: {create_resp.user.id}") ``` * Go import\_users.go ```go 1 newUser := &usersv1.CreateUser{ 2 Email: row.Email, 3 ExternalId: row.UserID, // Auth0 user_id, e.g. "auth0|abc123" 4 UserProfile: &usersv1.CreateUserProfile{ 5 FirstName: row.GivenName, 6 LastName: row.FamilyName, 7 }, 8 } 9 10 cuResp, err := scalekitClient.User().CreateUserAndMembership(ctx, organizationID, newUser, false) 11 if err != nil { 12 log.Fatal(err) 13 } 14 fmt.Printf("Created user: %s\n", cuResp.User.Id) ``` * Java ImportUsers.java ```java 1 CreateUser createUser = CreateUser.newBuilder() 2 .setEmail(row.email) 3 .setExternalId(row.userId) // Auth0 user_id, e.g. "auth0|abc123" 4 .setUserProfile( 5 CreateUserProfile.newBuilder() 6 .setFirstName(row.givenName) 7 .setLastName(row.familyName) 8 .build()) 9 .build(); 10 11 CreateUserAndMembershipResponse cuResp = scalekitClient.users() 12 .createUserAndMembership(organizationId, createUser); 13 System.out.println("Created user: " + cuResp.getUser().getId()); ``` Batch the import and run requests in parallel for speed, but respect rate limits. Roles referenced on the membership must exist first. Create them under **User Management > Roles** or with the SDK. See [Create roles and permissions](/authenticate/authz/create-roles-permissions/). 5. ## Rebuild enterprise SSO connections [Section titled “Rebuild enterprise SSO connections”](#rebuild-enterprise-sso-connections) For every customer that signed in through an Auth0 enterprise connection, recreate the connection in Scalekit against the same identity provider. You configure this per organization, so each customer keeps its own SAML or OIDC setup. Follow [Add modular SSO](/authenticate/sso/add-modular-sso/) for each organization. Reuse the identity provider metadata you recorded during export, then re-run the identity provider’s setup to issue fresh SAML or OIDC credentials to Scalekit. Connection secrets from Auth0 cannot be reused. 6. ## Point your app at Scalekit hosted login [Section titled “Point your app at Scalekit hosted login”](#point-your-app-at-scalekit-hosted-login) Replace the Auth0 login redirect and session validation with Scalekit. * Register your callback and post-logout URLs under **Settings > Redirects**. See the [redirect URI guide](/guides/dashboard/redirects/). * Swap Auth0 SDK session middleware for the Scalekit SDK, or validate access tokens against Scalekit’s JWKS endpoint. * Read authorization from the `roles` claim that Scalekit issues, in place of Auth0 roles or scopes. 7. ## Cut over incrementally and verify [Section titled “Cut over incrementally and verify”](#cut-over-incrementally-and-verify) Roll out behind a feature flag so you can reverse the switch without a redeploy. 1. Route 5 to 10 percent of traffic to Scalekit login and confirm those users authenticate, receive sessions, and see the right roles. 2. Watch authentication success rates and error logs. Verify SSO connections resolve for enterprise organizations. 3. Increase the percentage in stages until all traffic uses Scalekit. 4. Keep the Auth0 tenant read-only until you’re confident, so rollback stays available. ## Handle password-based users [Section titled “Handle password-based users”](#handle-password-based-users) Auth0 database users authenticate with a password hash that stays inside Auth0 and can’t be exported. Two paths keep those users signed in: * **Re-authentication (recommended).** On first visit after cutover, users sign in through SSO, social login, or [passwordless](/authenticate/auth-methods/passwordless/). No password moves, and the `external_id` mapping links them back to their imported record. * **Password-hash migration.** If you must carry password hashes over, the Scalekit Solutions team handles this directly. [Contact us](/support/contact-us) before you start the import. ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Where to go next [Section titled “Where to go next”](#where-to-go-next) * [Migrate to Full Stack Auth](/fsa/guides/migration-guide/): the vendor-neutral migration reference this recipe builds on. * [Add modular SSO](/authenticate/sso/add-modular-sso/): rebuild each enterprise connection in Scalekit. * [Create roles and permissions](/authenticate/authz/create-roles-permissions/): set up the roles your imported memberships reference. STYLE-CHECK: PASSED --- # DOCUMENT BOUNDARY --- # Build a multi-user GitHub PR summarizer agent > Build a GitHub PR summarizer that binds each connected GitHub account to a secure browser session instead of trusting a client-supplied user ID. This recipe builds a GitHub PR summarizer with a browser UI and a secure connected-account flow. Each user connects GitHub once, then the app reuses that connected token for later PR summary requests in the same browser session. The important security rule is straightforward: **never accept a user ID from the browser and use it as the Scalekit connected-account identifier**. Instead, mint an opaque identifier on the server, store it in your own session store, and complete the flow with [user verification for connected accounts](/agentkit/user-verification/). The finished app does four things: * lists the most-discussed open pull requests in a repository * fetches each PR’s diff and comment thread through Scalekit’s GitHub connector * asks an LLM to summarize the PRs in plain language * binds every GitHub connection to a secure browser session instead of a client-supplied identifier The complete source is available in the [render-ai-agent-deploykit](https://github.com/scalekit-developers/render-ai-agent-deploykit) repository. You can also [watch the video walkthrough](https://youtu.be/w3atzSkKE1w) to see the full setup and demo end-to-end. ## What you are building [Section titled “What you are building”](#what-you-are-building) The app runs as a Node web service on Render. It serves an HTML page with a **Connect GitHub** button and a form for `owner` and `repo`. Under the hood, the flow looks like this: ```text 1 Browser (original tab) Browser (new tab) 2 │ │ 3 ▼ GET / │ 4 Express server sets signed session cookie │ 5 │ │ 6 ▼ POST /api/auth │ 7 Scalekit returns GitHub auth link │ 8 │ │ 9 │ opens auth link ─────────────────► ▼ 10 │ GitHub OAuth consent 11 │ │ 12 │ polls GET /api/auth/status ▼ 13 │ ◄─── Scalekit API: ACTIVE ──► Scalekit verifies account 14 │ 15 ▼ page auto-reloads 16 │ 17 ▼ POST /api/summarize { repository } 18 Scalekit runs GitHub requests with the connected user's token ``` The OAuth flow opens in a **new tab** so the app page stays intact. The original tab polls the Scalekit API until the connected account becomes `ACTIVE`, then auto-reloads to show the connected state. ## 1. Set up the GitHub connector [Section titled “1. Set up the GitHub connector”](#1-set-up-the-github-connector) Create the connector once per Scalekit environment. 1. Go to [app.scalekit.com](https://app.scalekit.com) → **AgentKit** > **Connections** > **Create Connection** 2. Find **GitHub** and click **Create** 3. Follow the setup — Scalekit creates and manages the GitHub OAuth app for you 4. Note the **connection name** assigned (e.g. `github-qkHFhMip`) — you’ll set this as `GITHUB_CONNECTION_NAME` in your environment Connection names are unique per environment Scalekit generates a unique GitHub connection name for each environment. Do not copy one from a tutorial or another project. Always use the exact value from your own Scalekit Dashboard. ## 2. Configure user verification (required) [Section titled “2. Configure user verification (required)”](#2-configure-user-verification-required) Scalekit’s user verification setting controls what happens after a user completes GitHub OAuth. **You must choose a mode in the dashboard before the app will work end-to-end.** Go to **AgentKit > Settings > User verification** in the [Scalekit dashboard](https://app.scalekit.com). | Mode | When to use | What happens after OAuth | | ---------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Scalekit users only** | Development and testing | Scalekit verifies the user internally. The connected account goes `ACTIVE` automatically. The app detects this by polling the Scalekit API. | | **Custom user verification** | Production | Scalekit redirects the browser to your app’s `/user/verify` callback. The server calls `verifyConnectedAccountUser` to activate the account. The app also polls the Scalekit API as a fallback. | The app works in **both modes** without code changes. If you skip this step entirely, the connected account may never reach `ACTIVE` status and the app will stay stuck on “Waiting for GitHub authorization.” This step is required This is the most common setup mistake. If you deploy the app, set all environment variables, and complete GitHub OAuth but the app never shows “GitHub connected,” check this dashboard setting first. For the full verification model, see [user verification for connected accounts](/agentkit/user-verification/). ## 3. Create the project [Section titled “3. Create the project”](#3-create-the-project) Terminal ```bash 1 mkdir render-pr-summarizer && cd render-pr-summarizer 2 npm init -y 3 npm install @renderinc/sdk @scalekit-sdk/node openai dotenv express 4 npm install -D typescript tsx @types/node @types/express ``` package.json ```json 1 { 2 "type": "module", 3 "scripts": { 4 "dev": "tsx src/main.ts", 5 "build": "tsc", 6 "start": "node dist/main.js" 7 } 8 } ``` tsconfig.json ```json 1 { 2 "compilerOptions": { 3 "target": "ES2022", 4 "module": "NodeNext", 5 "moduleResolution": "NodeNext", 6 "outDir": "dist", 7 "strict": true 8 }, 9 "include": ["src"] 10 } ``` ## 4. Configure environment variables [Section titled “4. Configure environment variables”](#4-configure-environment-variables) Terminal ```bash 1 cp .env.example .env ``` .env ```bash 1 PORT=3000 2 SESSION_SECRET=replace-with-openssl-rand-hex-32 3 4 OPENAI_API_KEY=your-api-key 5 OPENAI_MODEL=gpt-4.1-mini 6 # Leave OPENAI_BASE_URL empty for OpenAI direct. 7 # Set it to a proxy URL for LiteLLM, Azure OpenAI, Ollama, etc. 8 # OPENAI_BASE_URL=https://your-litellm-proxy.example.com 9 10 SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com 11 SCALEKIT_CLIENT_ID=your-scalekit-client-id 12 SCALEKIT_CLIENT_SECRET=your-scalekit-client-secret 13 GITHUB_CONNECTION_NAME=your-github-connection-name 14 15 # Optional — the app auto-detects its public URL from proxy headers. 16 # Only set this if you need to pin the callback origin explicitly. 17 # PUBLIC_BASE_URL=http://localhost:3000 ``` Generate `SESSION_SECRET` with: Terminal ```bash 1 openssl rand -hex 32 ``` ## 5. Add Scalekit auth helpers [Section titled “5. Add Scalekit auth helpers”](#5-add-scalekit-auth-helpers) The helper layer creates connected accounts, generates auth links, verifies the callback, and routes GitHub API calls through Scalekit’s connector. src/scalekit.ts ```typescript 1 import "dotenv/config"; 2 import { ScalekitClient } from "@scalekit-sdk/node"; 3 import type { JsonObject } from "@bufbuild/protobuf"; 4 5 let _scalekit: ScalekitClient | null = null; 6 7 function getScalekit(): ScalekitClient { 8 if (_scalekit) return _scalekit; 9 if (!process.env.SCALEKIT_ENVIRONMENT_URL || !process.env.SCALEKIT_CLIENT_ID || !process.env.SCALEKIT_CLIENT_SECRET) { 10 throw new Error("Missing SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, or SCALEKIT_CLIENT_SECRET"); 11 } 12 _scalekit = new ScalekitClient( 13 process.env.SCALEKIT_ENVIRONMENT_URL, 14 process.env.SCALEKIT_CLIENT_ID, 15 process.env.SCALEKIT_CLIENT_SECRET, 16 ); 17 return _scalekit; 18 } 19 20 export const scalekit = new Proxy({} as ScalekitClient, { 21 get(_target, prop) { 22 return (getScalekit() as unknown as Record)[prop]; 23 }, 24 }); 25 26 const GITHUB_CONNECTION_NAME = process.env.GITHUB_CONNECTION_NAME; 27 if (!GITHUB_CONNECTION_NAME) { 28 throw new Error( 29 "GITHUB_CONNECTION_NAME is required. Copy the connection name from Scalekit Dashboard > Agent Auth > Connectors.", 30 ); 31 } 32 33 export async function getGitHubAuthLink( 34 identifier: string, 35 opts: { state: string; userVerifyUrl: string }, 36 ): Promise { 37 await scalekit.actions.getOrCreateConnectedAccount({ 38 connectionName: GITHUB_CONNECTION_NAME, 39 identifier, 40 }); 41 42 const res = await scalekit.actions.getAuthorizationLink({ 43 connectionName: GITHUB_CONNECTION_NAME, 44 identifier, 45 state: opts.state, 46 userVerifyUrl: opts.userVerifyUrl, 47 }); 48 49 if (!res.link) { 50 throw new Error( 51 `Scalekit did not return a GitHub authorization link for '${GITHUB_CONNECTION_NAME}' and identifier '${identifier}'`, 52 ); 53 } 54 55 return res.link; 56 } 57 58 export async function verifyUser(params: { 59 authRequestId: string; 60 identifier: string; 61 }): Promise { 62 await scalekit.actions.verifyConnectedAccountUser({ 63 authRequestId: params.authRequestId, 64 identifier: params.identifier, 65 }); 66 } 67 68 /** 69 * Check the connected account status via Scalekit API. 70 * Returns true when the account is active (OAuth complete and verified). 71 */ 72 export async function isAccountActive(identifier: string): Promise { 73 try { 74 const res = await scalekit.actions.getConnectedAccount({ 75 connectionName: GITHUB_CONNECTION_NAME, 76 identifier, 77 }); 78 // ConnectorStatus.ACTIVE === 1 79 return res.connectedAccount?.status === 1; 80 } catch { 81 return false; 82 } 83 } 84 85 export async function githubTool( 86 identifier: string, 87 toolName: string, 88 toolInput: Record, 89 ): Promise { 90 const res = await scalekit.actions.executeTool({ 91 toolName, 92 toolInput, 93 connector: GITHUB_CONNECTION_NAME, 94 identifier, 95 }); 96 97 return res.data ?? {}; 98 } 99 100 export async function githubRequest( 101 identifier: string, 102 path: string, 103 options: { 104 method?: string; 105 headers?: Record; 106 queryParams?: Record; 107 } = {}, 108 ) { 109 const res = await scalekit.actions.request({ 110 connectionName: GITHUB_CONNECTION_NAME, 111 identifier, 112 path, 113 method: options.method ?? "GET", 114 headers: options.headers, 115 queryParams: options.queryParams, 116 }); 117 118 return res.data; 119 } ``` Use the exact connector name The `connector` value in `executeTool` must be the full connection name from your own Scalekit environment, not the generic provider string `"github"`. ## 6. Bind the browser session to an opaque identifier [Section titled “6. Bind the browser session to an opaque identifier”](#6-bind-the-browser-session-to-an-opaque-identifier) The session layer is the security boundary for the whole app. Create `src/session.ts` and store three things: * a signed session cookie sent to the browser * an opaque `usr_...` identifier stored on the server * a one-time `state` value stored on the server while OAuth is in flight src/session.ts ```typescript 1 import { createHmac, randomBytes, timingSafeEqual } from "node:crypto"; 2 import type { Request, Response } from "express"; 3 4 const COOKIE_NAME = "sid"; 5 const STATE_TTL_MS = 10 * 60 * 1000; 6 7 interface SessionEntry { 8 identifier: string; 9 pendingState?: string; 10 pendingStateExpiresAt?: number; 11 connectedAt?: number; 12 } 13 14 const store = new Map(); 15 16 function getSecret(): string { 17 const secret = process.env.SESSION_SECRET; 18 if (!secret) { 19 throw new Error("SESSION_SECRET is required"); 20 } 21 return secret; 22 } 23 24 function sign(sessionId: string): string { 25 const mac = createHmac("sha256", getSecret()).update(sessionId).digest("base64url"); 26 return `${sessionId}.${mac}`; 27 } 28 29 function unsign(signed: string): string | null { 30 const dot = signed.lastIndexOf("."); 31 if (dot < 0) return null; 32 33 const sessionId = signed.slice(0, dot); 34 const mac = signed.slice(dot + 1); 35 const expected = createHmac("sha256", getSecret()).update(sessionId).digest("base64url"); 36 37 const expectedBuf = Buffer.from(expected); 38 const macBuf = Buffer.from(mac); 39 if (expectedBuf.length !== macBuf.length) return null; 40 41 return timingSafeEqual(expectedBuf, macBuf) ? sessionId : null; 42 } 43 44 export function requireSession(req: Request, res: Response) { 45 const cookies = Object.fromEntries( 46 (req.headers.cookie ?? "") 47 .split(";") 48 .flatMap((pair) => { 49 const eq = pair.indexOf("="); 50 if (eq < 0) return []; 51 try { 52 return [[pair.slice(0, eq).trim(), decodeURIComponent(pair.slice(eq + 1).trim())]]; 53 } catch { 54 return []; 55 } 56 }), 57 ); 58 59 const raw = cookies[COOKIE_NAME]; 60 let sessionId = raw ? unsign(raw) : null; 61 let entry = sessionId ? store.get(sessionId) ?? null : null; 62 63 if (!sessionId || !entry) { 64 sessionId = randomBytes(32).toString("base64url"); 65 entry = { identifier: "" }; 66 store.set(sessionId, entry); 67 } 68 69 // The cookie only carries a random opaque session id. HMAC signing is enough 70 // to detect tampering because the sensitive identifier stays server-side. 71 const protoHeader = req.get("x-forwarded-proto"); 72 const requestIsSecure = req.secure || protoHeader?.split(",")[0]?.trim() === "https"; 73 const secure = 74 process.env.NODE_ENV === "production" || 75 process.env.PUBLIC_BASE_URL?.startsWith("https://") === true || 76 requestIsSecure; 77 const parts = [ 78 `${COOKIE_NAME}=${sign(sessionId)}`, 79 "HttpOnly", 80 "SameSite=Lax", 81 "Path=/", 82 `Max-Age=${7 * 24 * 60 * 60}`, 83 ]; 84 if (secure) parts.push("Secure"); 85 res.setHeader("Set-Cookie", parts.join("; ")); 86 87 return { entry }; 88 } 89 90 export function mintIdentifier(entry: SessionEntry): string { 91 if (!entry.identifier) { 92 entry.identifier = `usr_${randomBytes(16).toString("hex")}`; 93 } 94 return entry.identifier; 95 } 96 97 export function setPendingState(entry: SessionEntry, state: string): void { 98 entry.pendingState = state; 99 entry.pendingStateExpiresAt = Date.now() + STATE_TTL_MS; 100 } 101 102 export function consumePendingState(entry: SessionEntry, incoming: string): boolean { 103 const stored = entry.pendingState; 104 const expiresAt = entry.pendingStateExpiresAt; 105 entry.pendingState = undefined; 106 entry.pendingStateExpiresAt = undefined; 107 108 if (!stored || !expiresAt || Date.now() > expiresAt) return false; 109 110 const storedBuf = Buffer.from(stored); 111 const incomingBuf = Buffer.from(incoming); 112 if (storedBuf.length !== incomingBuf.length) return false; 113 114 return timingSafeEqual(storedBuf, incomingBuf); 115 } 116 117 export function markConnected(entry: SessionEntry): void { 118 entry.connectedAt = Date.now(); 119 } 120 121 export function isConnected(entry: SessionEntry): boolean { 122 return entry.connectedAt !== undefined; 123 } ``` Never trust query params for identity Read the identifier from your own session store, not from the URL and not from the request body. The callback query string only proves that Scalekit completed an OAuth flow. Your server must decide which local user session owns that new connection. ## 7. Add the tasks [Section titled “7. Add the tasks”](#7-add-the-tasks) The task layer now accepts a server-side `identifier`, not a browser-supplied `userId`. src/tasks.ts ```typescript 1 import { task } from "@renderinc/sdk/workflows"; 2 import OpenAI from "openai"; 3 import { githubRequest, githubTool, getGitHubAuthLink } from "./scalekit.js"; 4 5 export interface PRSummaryInput { 6 identifier: string; 7 owner: string; 8 repo: string; 9 } 10 11 const fetchOpenPRs = task( 12 { name: "fetchOpenPRs", retry: { maxRetries: 3, waitDurationMs: 1000 } }, 13 async function fetchOpenPRs(identifier: string, owner: string, repo: string) { 14 const raw = await githubTool(identifier, "github_pull_requests_list", { 15 owner, 16 repo, 17 state: "open", 18 }); 19 20 const r = raw as Record; 21 const list = Array.isArray(raw) 22 ? raw 23 : Array.isArray(r.array) ? r.array 24 : Array.isArray(r.pull_requests) ? r.pull_requests 25 : Array.isArray(r.data) ? r.data 26 : null; 27 28 if (!list) { 29 throw new Error(`Unexpected response shape: ${JSON.stringify(raw).slice(0, 200)}`); 30 } 31 32 type PRItem = { number: number; title: string; comments: number; review_comments: number }; 33 return (list as PRItem[]) 34 .sort((a, b) => (b.comments + b.review_comments) - (a.comments + a.review_comments)) 35 .slice(0, 5); 36 }, 37 ); 38 39 const fetchPRDetails = task( 40 { name: "fetchPRDetails", retry: { maxRetries: 3, waitDurationMs: 1000 } }, 41 async function fetchPRDetails(identifier: string, owner: string, repo: string, prNumber: number) { 42 const [diffRaw, commentsRaw] = await Promise.all([ 43 githubRequest(identifier, `/repos/${owner}/${repo}/pulls/${prNumber}`, { 44 headers: { Accept: "application/vnd.github.diff" }, 45 }), 46 githubRequest(identifier, `/repos/${owner}/${repo}/issues/${prNumber}/comments`), 47 ]); 48 49 const diff = typeof diffRaw === "string" ? diffRaw.slice(0, 3000) : ""; 50 const comments = Array.isArray(commentsRaw) ? commentsRaw : []; 51 52 return { diff, comments }; 53 }, 54 ); 55 56 export const setupGitHubAuthTask = task( 57 { name: "setupGitHubAuth" }, 58 async function setupGitHubAuth(params: { 59 identifier: string; 60 state: string; 61 userVerifyUrl: string; 62 }) { 63 const link = await getGitHubAuthLink(params.identifier, { 64 state: params.state, 65 userVerifyUrl: params.userVerifyUrl, 66 }); 67 68 return { authLink: link }; 69 }, 70 ); 71 72 // ---- LLM summary ---- 73 74 function createOpenAIClient(): OpenAI { 75 const apiKey = process.env.OPENAI_API_KEY; 76 if (!apiKey) throw new Error("OPENAI_API_KEY not set"); 77 return new OpenAI({ 78 apiKey, 79 ...(process.env.OPENAI_BASE_URL && { baseURL: process.env.OPENAI_BASE_URL }), 80 }); 81 } 82 83 const generateSummary = task( 84 { name: "generateSummary", retry: { maxRetries: 3, waitDurationMs: 2000 } }, 85 async function generateSummary( 86 prs: { number: number; title: string; diff: string; comments: { body?: string }[] }[], 87 owner: string, 88 repo: string, 89 ): Promise { 90 if (prs.length === 0) return "No open pull requests found in this repository."; 91 92 const client = createOpenAIClient(); 93 const prBlocks = prs 94 .map((pr) => { 95 const bodies = pr.comments.slice(0, 5).map((c) => `> ${(c.body ?? "").slice(0, 300)}`).join("\n"); 96 return `PR #${pr.number} — ${pr.title}\n${bodies || "No comments."}\nDiff:\n${pr.diff || "(not available)"}`; 97 }) 98 .join("\n\n---\n\n"); 99 100 const response = await client.chat.completions.create({ 101 model: process.env.OPENAI_MODEL ?? "gpt-4.1-mini", 102 messages: [ 103 { 104 role: "system", 105 content: 106 "Summarize each PR in one paragraph (3-4 sentences) for a team lead. " + 107 "Cover what it does, how much discussion happened, and whether it looks close to merging.", 108 }, 109 { role: "user", content: `Repository: ${owner}/${repo}\n\n${prBlocks}` }, 110 ], 111 }); 112 113 return response.choices[0].message.content ?? "(no summary generated)"; 114 }, 115 ); 116 117 // ---- Root task ---- 118 119 export const summarizePRsTask = task( 120 { name: "summarizePRs", timeoutSeconds: 120 }, 121 async function summarizePRs(input: PRSummaryInput) { 122 const { identifier, owner, repo } = input; 123 const topPRs = await fetchOpenPRs(identifier, owner, repo); 124 125 if (topPRs.length === 0) { 126 return { repository: `${owner}/${repo}`, prsAnalyzed: [] as string[], summary: "No open pull requests found." }; 127 } 128 129 const details = await Promise.all( 130 topPRs.map((pr) => fetchPRDetails(identifier, owner, repo, pr.number)), 131 ); 132 133 const prsForSummary = topPRs.map((pr, i) => ({ 134 number: pr.number, 135 title: pr.title, 136 diff: details[i].diff, 137 comments: details[i].comments as { body?: string }[], 138 })); 139 140 const summary = await generateSummary(prsForSummary, owner, repo); 141 142 return { 143 repository: `${owner}/${repo}`, 144 prsAnalyzed: topPRs.map((p) => `#${p.number}: ${p.title}`), 145 summary, 146 }; 147 }, 148 ); ``` ## 8. Wire the HTTP server [Section titled “8. Wire the HTTP server”](#8-wire-the-http-server) The HTTP server owns the secure flow. It issues the session cookie, starts the GitHub auth flow, validates the callback, and blocks summary requests until the session is connected. src/server.ts ```typescript 1 import crypto from "node:crypto"; 2 import express from "express"; 3 import { setupGitHubAuthTask, summarizePRsTask } from "./tasks.js"; 4 import { isAccountActive, verifyUser } from "./scalekit.js"; 5 import { 6 consumePendingState, 7 isConnected, 8 markConnected, 9 mintIdentifier, 10 requireSession, 11 setPendingState, 12 } from "./session.js"; 13 import { renderHomePage, renderAuthCompletePage } from "./views.js"; 14 import type { Request } from "express"; 15 16 function getConfiguredPublicBaseUrl(): string | null { 17 const value = process.env.PUBLIC_BASE_URL; 18 return value ? value.replace(/\/$/, "") : null; 19 } 20 21 function getRequestOrigin(req: Request): string { 22 const configured = getConfiguredPublicBaseUrl(); 23 if (configured) return configured; 24 25 const protoHeader = req.get("x-forwarded-proto"); 26 const proto = protoHeader?.split(",")[0]?.trim() || req.protocol || "http"; 27 const host = req.get("x-forwarded-host") || req.get("host"); 28 if (!host) { 29 throw new Error("Could not determine the public origin for this request"); 30 } 31 return `${proto}://${host}`; 32 } 33 34 export function startServer(): void { 35 const app = express(); 36 app.set("trust proxy", true); 37 app.use(express.json()); 38 39 app.get("/", (req, res) => { 40 const { entry } = requireSession(req, res); 41 res.type("html").send(renderHomePage({ connected: isConnected(entry) })); 42 }); 43 44 // Polled by the original tab while the OAuth tab is open. 45 // Checks the in-memory session first, then queries the Scalekit API 46 // to detect when the connected account becomes ACTIVE. 47 app.get("/api/auth/status", async (req, res) => { 48 const { entry } = requireSession(req, res); 49 if (isConnected(entry)) { 50 res.json({ connected: true }); 51 return; 52 } 53 if (entry.identifier && await isAccountActive(entry.identifier)) { 54 markConnected(entry); 55 res.json({ connected: true }); 56 return; 57 } 58 res.json({ connected: false }); 59 }); 60 61 app.post("/api/auth", async (req, res) => { 62 const { entry } = requireSession(req, res); 63 const identifier = mintIdentifier(entry); 64 65 const state = crypto.randomUUID(); 66 setPendingState(entry, state); 67 68 const result = await setupGitHubAuthTask({ 69 identifier, 70 state, 71 userVerifyUrl: `${getRequestOrigin(req)}/user/verify`, 72 }); 73 74 res.json({ authLink: result.authLink }); 75 }); 76 77 // Callback for custom user verification mode. When Scalekit is 78 // configured in "Scalekit users only" mode, this route may not fire — 79 // the /api/auth/status polling handles that case via the Scalekit API. 80 app.get("/user/verify", async (req, res) => { 81 const { auth_request_id, state } = req.query as Record; 82 if (!auth_request_id || !state) { 83 res.status(400).send("Missing auth_request_id or state"); 84 return; 85 } 86 87 const { entry } = requireSession(req, res); 88 if (!entry.identifier) { 89 res.status(400).send("No pending authorization for this session"); 90 return; 91 } 92 93 if (!consumePendingState(entry, state)) { 94 res.status(400).send("Invalid or expired state"); 95 return; 96 } 97 98 await verifyUser({ 99 authRequestId: auth_request_id, 100 identifier: entry.identifier, 101 }); 102 103 markConnected(entry); 104 // This handler runs in the OAuth tab. Render a minimal page 105 // telling the user to close it — the original tab is polling 106 // /api/auth/status and will auto-reload. 107 res.type("html").send(renderAuthCompletePage()); 108 }); 109 110 app.post("/api/summarize", async (req, res) => { 111 const { entry } = requireSession(req, res); 112 if (!isConnected(entry)) { 113 res.status(401).json({ error: "Connect your GitHub account first" }); 114 return; 115 } 116 117 // The UI sends { repository: "https://github.com/owner/repo" } or "owner/repo". 118 // Parse the string into separate owner and repo values. 119 const { repository } = req.body as { repository?: string }; 120 if (!repository) { 121 res.status(400).json({ error: "Provide a GitHub repository URL or owner/repo name." }); 122 return; 123 } 124 125 let owner: string | undefined; 126 let repo: string | undefined; 127 try { 128 const url = new URL(repository); 129 const segments = url.pathname.split("/").filter(Boolean); 130 owner = segments[0]; 131 repo = segments[1]?.replace(/\.git$/, ""); 132 } catch { 133 const parts = repository.split("/"); 134 owner = parts[0]; 135 repo = parts[1]?.replace(/\.git$/, ""); 136 } 137 138 if (!owner || !repo) { 139 res.status(400).json({ error: "Provide a GitHub repository URL or owner/repo name." }); 140 return; 141 } 142 143 const result = await summarizePRsTask({ identifier: entry.identifier, owner, repo }); 144 res.json(result); 145 }); 146 } ``` ## 9. Render the browser UI [Section titled “9. Render the browser UI”](#9-render-the-browser-ui) The UI only asks for a repository. It does not ask for a user identifier. After a successful connection, the page auto-reloads and shows a connected banner. The key change from a naive implementation: `connectGitHub()` opens the auth link in a **new tab** instead of navigating the current page. This keeps the app intact even if the OAuth redirect chain doesn’t return cleanly. The original tab polls `/api/auth/status` and auto-reloads when the Scalekit API reports the account as `ACTIVE`. src/views.ts ```typescript 1 export function renderAuthCompletePage(): string { 2 return ` 3 4 5
6

✓ GitHub connected

7

You can close this tab and return to the app. The original page will update automatically.

8
9 10 `; 11 } 12 13 export function renderHomePage({ connected }: { connected: boolean }): string { 14 const connectedBanner = connected 15 ? `
✓ GitHub connected
` 16 : `
Connect GitHub before summarizing pull requests.
`; 17 const authButtonLabel = connected ? "Reconnect GitHub" : "Connect GitHub"; 18 19 return ` 20 21 22 ${connectedBanner} 23 24
25 26 27

28
      
88
    
89
  `;
90
}
```
 ## 10. Run locally [Section titled “10. Run locally”](#10-run-locally) 1. Copy `.env.example` to `.env` and fill in your values. 2. Run `npm install`. 3. Run `npm run dev`. 4. Open `http://localhost:3000`. 5. Click **Connect GitHub**. A new tab opens for the GitHub OAuth flow. 6. Complete the OAuth consent in the new tab. 7. The new tab shows “GitHub connected — you can close this tab” (in custom verification mode) or a Scalekit success page (in Scalekit-users-only mode). 8. The original tab auto-detects the connection and reloads, showing a **GitHub connected** banner. 9. Enter a repository URL or `owner/repo`, then generate a summary. Public repositories work with any connected GitHub account. Private repositories only work if the connected account has access. ## 11. Deploy to Render [Section titled “11. Deploy to Render”](#11-deploy-to-render) Render deploys the app as a web service from `render.yaml`. Set these environment variables in Render: | Variable | Required | Notes | | -------------------------- | -------- | --------------------------------------------------------------------- | | `SCALEKIT_ENVIRONMENT_URL` | Yes | From Scalekit dashboard → Developers → API Credentials | | `SCALEKIT_CLIENT_ID` | Yes | Same location | | `SCALEKIT_CLIENT_SECRET` | Yes | Same location | | `GITHUB_CONNECTION_NAME` | Yes | From AgentKit → Connectors | | `OPENAI_API_KEY` | Yes | OpenAI key or proxy token | | `OPENAI_BASE_URL` | No | Leave empty for OpenAI direct. Set for LiteLLM/Azure/Ollama. | | `OPENAI_MODEL` | No | Default: `gpt-4.1-mini` | | `SESSION_SECRET` | Auto | `render.yaml` auto-generates this | | `PUBLIC_BASE_URL` | No | Auto-detected from proxy headers. Only needed behind a custom domain. | After deploying, configure user verification in the Scalekit dashboard ([step 2](#2-configure-user-verification-required)). The app will not complete the GitHub connection flow without this. ## Production notes [Section titled “Production notes”](#production-notes) * **User verification mode**: Switch to **Custom user verification** in the Scalekit dashboard before going to production. This ensures your backend confirms which session owns each new connection. * **Shared session store**: The sample stores session data in memory. Use Redis or a database-backed shared store in production. * **Short-lived OAuth state**: The sample expires the pending `state` after 10 minutes and consumes it after a single callback. * **Session-bound identifier**: The browser never chooses the identifier that Scalekit uses to look up the connected account. * **Connector-backed GitHub requests**: The sample routes both PR listing and PR detail fetches through Scalekit so the connected user’s token is used consistently. ## Next steps [Section titled “Next steps”](#next-steps) * Read [user verification for connected accounts](/agentkit/user-verification/) for the full verification model and additional examples. * Read [authorize a user](/agentkit/tools/authorize/) for the status-polling pattern used to detect when a connected account becomes `ACTIVE`. * Open the [render-ai-agent-deploykit](https://github.com/scalekit-developers/render-ai-agent-deploykit) repository to compare the full implementation against the snippets in this cookbook.

---
# DOCUMENT BOUNDARY
---

# Build an agent that books meetings and drafts emails

> Connect a Python agent to Google Calendar and Gmail via Scalekit to find free slots, book meetings, and draft follow-up emails.

Scheduling a meeting sounds simple: find a free slot, create an event, send a confirmation. But in an agent, each of those steps crosses a tool boundary — and each tool requires its own OAuth token. Without a managed auth layer, you end up writing token-fetching, refresh logic, and error handling three times over before you write a single line of scheduling logic. This cookbook solves that by using Scalekit to own the OAuth lifecycle for each connector, so your agent can focus on the workflow itself. This is a Python recipe for agents that call two or more external APIs on behalf of a user. If you’re using a service account rather than user-delegated OAuth, or building in JavaScript, the pattern is the same but the source differs — see the `javascript/` track in [agent-auth-examples](https://github.com/scalekit-developers/agent-auth-examples). The complete Python source used here is `python/meeting_scheduler_agent.py` in that repo. **The core problems this solves:** * **One token per connector** — Google Calendar and Gmail use separate OAuth scopes and separate access tokens. Your agent must manage both independently. * **First-run authorization is blocking** — If the user has not yet authorized a connector, your agent cannot proceed until they complete the browser OAuth flow. * **Token expiry is silent** — A token that worked yesterday fails today, and the failure looks identical to a permissions error. * **Chaining tool outputs is fragile** — The event link from the Calendar API needs to appear in the Gmail draft. If the Calendar call fails mid-workflow, the draft gets a broken link or never gets created. Scalekit exposes a `connected_accounts` abstraction that maps a user ID to an authorized OAuth session per connector. When your agent calls `get_or_create_connected_account`, Scalekit either returns an existing active account with a valid token or creates a new one and returns an authorization URL. Once the user authorizes, `get_connected_account` returns the token. From that point, Scalekit handles refresh automatically. This means your agent’s authorization step is a single function regardless of which connector you’re targeting. The rest of the code — Calendar queries, event creation, Gmail drafts — is plain HTTP with the token Scalekit provides. 1. **Set up the environment** Create a `.env` file at the project root with your Scalekit credentials: 
   ```bash
   1
   SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com
   2
   SCALEKIT_CLIENT_ID=your-client-id
   3
   SCALEKIT_CLIENT_SECRET=your-client-secret
   ```
 Install dependencies: 
   ```bash
   1
   pip install scalekit-sdk python-dotenv requests
   ```
 In the Scalekit Dashboard, create two connections for your environment: * `googlecalendar` — Google Calendar OAuth connection * `gmail` — Gmail OAuth connection The script references these names literally. The names must match exactly. 2. **Initialize the Scalekit client** meeting\_scheduler\_agent.py 
   ```python
   1
   import os
   2
   import base64
   3
   from datetime import datetime, timezone, timedelta
   4
   from email.mime.text import MIMEText
   5


   6
   import requests
   7
   from dotenv import load_dotenv
   8
   from scalekit import ScalekitClient
   9


   10
   load_dotenv()
   11


   12
   # Never hard-code credentials — they would be exposed in source control
   13
   # and CI logs. Pull them from environment variables instead.
   14
   scalekit_client = ScalekitClient(
   15
       environment_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
   16
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
   17
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   18
   )
   19


   20
   actions = scalekit_client.actions
   21


   22
   # Replace with a real user identifier from your application's session
   23
   USER_ID = "user_123"
   24
   ATTENDEE_EMAIL = "attendee@example.com"
   25
   MEETING_TITLE = "Quick Sync"
   26
   DURATION_MINUTES = 60
   27
   SEARCH_DAYS = 3
   28
   WORK_START_HOUR = 9   # UTC
   29
   WORK_END_HOUR = 17    # UTC
   ```
 `scalekit_client.actions` is the entry point for all connected-account operations. Initialize it once and pass `actions` to the functions below. 3. **Authorize each connector** The `authorize` function handles the first-run prompt and returns a valid access token: 
   ```python
   1
   def authorize(connector: str) -> str:
   2
       """Ensure the user has an active connected account and return its access token.
   3


   4
       On first run, this prints an authorization URL and waits for the user
   5
       to complete the browser OAuth flow before continuing.
   6
       """
   7
       account = actions.get_or_create_connected_account(connector, USER_ID)
   8


   9
       if account.status != "active":
   10
           auth_link = actions.get_authorization_link(connector, USER_ID)
   11
           print(f"\nOpen this link to authorize {connector}:\n{auth_link}\n")
   12
           input("Press Enter after completing authorization in your browser…")
   13
           account = actions.get_connected_account(connector, USER_ID)
   14


   15
       return account.authorization_details["oauth_token"]["access_token"]
   ```
 Call this once per connector before any API calls: 
   ```python
   1
   calendar_token = authorize("googlecalendar")
   2
   gmail_token = authorize("gmail")
   ```
 After the first successful authorization, `get_or_create_connected_account` returns `status == "active"` on subsequent runs and the `if` block is skipped. Scalekit refreshes expired tokens automatically. 4. **Query calendar availability** With a valid Calendar token, query the `freeBusy` endpoint to get the user’s busy intervals: 
   ```python
   1
   def get_busy_slots(token: str) -> list[dict]:
   2
       """Fetch busy intervals for the user's primary calendar."""
   3
       now = datetime.now(timezone.utc)
   4
       window_end = now + timedelta(days=SEARCH_DAYS)
   5


   6
       response = requests.post(
   7
           "https://www.googleapis.com/calendar/v3/freeBusy",
   8
           headers={"Authorization": f"Bearer {token}"},
   9
           json={
   10
               "timeMin": now.isoformat(),
   11
               "timeMax": window_end.isoformat(),
   12
               "items": [{"id": "primary"}],
   13
           },
   14
       )
   15
       response.raise_for_status()
   16
       return response.json()["calendars"]["primary"]["busy"]
   ```
 `raise_for_status()` converts 4xx and 5xx responses into exceptions, so the caller sees a clear error rather than a silent wrong result. The `busy` list contains `{"start": "...", "end": "..."}` dicts in ISO 8601 format. 5. **Find the first open slot** Walk forward in one-hour increments from now and return the first candidate that falls within working hours and does not overlap a busy interval: 
   ```python
   1
   def find_free_slot(busy_slots: list[dict]) -> tuple[datetime, datetime] | None:
   2
       """Return the first open one-hour slot during working hours in UTC.
   3


   4
       Returns None if no slot is available in the search window.
   5
       """
   6
       now = datetime.now(timezone.utc)
   7
       # Round up to the next whole hour so the candidate is always in the future
   8
       candidate = now.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1)
   9
       window_end = now + timedelta(days=SEARCH_DAYS)
   10


   11
       while candidate < window_end:
   12
           slot_end = candidate + timedelta(minutes=DURATION_MINUTES)
   13


   14
           if WORK_START_HOUR <= candidate.hour < WORK_END_HOUR:
   15
               overlap = any(
   16
                   candidate < datetime.fromisoformat(b["end"])
   17
                   and slot_end > datetime.fromisoformat(b["start"])
   18
                   for b in busy_slots
   19
               )
   20
               if not overlap:
   21
                   return candidate, slot_end
   22


   23
           candidate += timedelta(hours=1)
   24


   25
       return None
   ```
 This is a useful first-draft strategy: simple, readable, easy to debug. Its limits are real (one-hour granularity, UTC-only, primary calendar only) and addressed in [Production notes](#production-notes) below. 6. **Create the calendar event** Post the event to the Google Calendar API and return its HTML link, which you’ll include in the email draft: 
   ```python
   1
   def create_event(token: str, start: datetime, end: datetime) -> str:
   2
       """Create a calendar event and return its HTML link."""
   3
       response = requests.post(
   4
           "https://www.googleapis.com/calendar/v3/calendars/primary/events",
   5
           headers={"Authorization": f"Bearer {token}"},
   6
           json={
   7
               "summary": MEETING_TITLE,
   8
               "description": "Scheduled by agent",
   9
               "start": {"dateTime": start.isoformat(), "timeZone": "UTC"},
   10
               "end": {"dateTime": end.isoformat(), "timeZone": "UTC"},
   11
               "attendees": [{"email": ATTENDEE_EMAIL}],
   12
           },
   13
       )
   14
       response.raise_for_status()
   15
       return response.json()["htmlLink"]
   ```
 The `htmlLink` in the response is the calendar event URL. Google also sends an invitation email to each attendee automatically when the event is created; the draft you create in the next step is a separate follow-up, not the invitation itself. 7. **Draft the confirmation email** Build the email body, base64-encode it, and post it to Gmail’s drafts endpoint: 
   ```python
   1
   def create_draft(token: str, event_link: str, start: datetime) -> None:
   2
       """Create a Gmail draft with the meeting details."""
   3
       body = (
   4
           f"Hi,\n\n"
   5
           f"I've scheduled '{MEETING_TITLE}' for "
   6
           f"{start.strftime('%A, %B %d at %H:%M UTC')} ({DURATION_MINUTES} min).\n\n"
   7
           f"Calendar link: {event_link}\n\n"
   8
           f"Looking forward to it!"
   9
       )
   10


   11
       message = MIMEText(body)
   12
       message["to"] = ATTENDEE_EMAIL
   13
       message["subject"] = f"Invitation: {MEETING_TITLE}"
   14


   15
       # Gmail's API requires the raw RFC 2822 message encoded as URL-safe base64
   16
       raw = base64.urlsafe_b64encode(message.as_bytes()).decode()
   17


   18
       response = requests.post(
   19
           "https://gmail.googleapis.com/gmail/v1/users/me/drafts",
   20
           headers={"Authorization": f"Bearer {token}"},
   21
           json={"message": {"raw": raw}},
   22
       )
   23
       response.raise_for_status()
   24
       print("Draft created in Gmail.")
   ```
 The script creates a draft, not a sent message. The user reviews it before sending. This is the right default for an agent — it takes the action but keeps a human in the loop for outbound communication. 8. **Wire it together** 
   ```python
   1
   def main() -> None:
   2
       print("Authorizing Google Calendar…")
   3
       calendar_token = authorize("googlecalendar")
   4


   5
       print("Authorizing Gmail…")
   6
       gmail_token = authorize("gmail")
   7


   8
       print("Checking calendar availability…")
   9
       busy_slots = get_busy_slots(calendar_token)
   10


   11
       slot = find_free_slot(busy_slots)
   12
       if not slot:
   13
           print(f"No free slot found in the next {SEARCH_DAYS} days.")
   14
           return
   15


   16
       start, end = slot
   17
       print(f"Found slot: {start.strftime('%A %B %d, %H:%M')} UTC")
   18


   19
       print("Creating calendar event…")
   20
       event_link = create_event(calendar_token, start, end)
   21
       print(f"Event created: {event_link}")
   22


   23
       print("Creating Gmail draft…")
   24
       create_draft(gmail_token, event_link, start)
   25


   26


   27
   if __name__ == "__main__":
   28
       main()
   ```
 ## Testing [Section titled “Testing”](#testing) Run the agent from the command line: 
```bash
1
python meeting_scheduler_agent.py
```
 On first run, you should see two authorization prompts in sequence: 
```plaintext
1
Authorizing Google Calendar…
2


3
Open this link to authorize googlecalendar:
4
https://accounts.google.com/o/oauth2/auth?...
5


6
Press Enter after completing authorization in your browser…
7


8
Authorizing Gmail…
9


10
Open this link to authorize gmail:
11
https://accounts.google.com/o/oauth2/auth?...
12


13
Press Enter after completing authorization in your browser…
14


15
Checking calendar availability…
16
Found slot: Wednesday March 11, 10:00 UTC
17
Creating calendar event…
18
Event created: https://calendar.google.com/calendar/event?eid=...
19
Creating Gmail draft…
20
Draft created in Gmail.
```
 On subsequent runs, the authorization prompts are skipped and the agent goes straight to availability checking. Verify the results: 1. Open Google Calendar — you should see the event on the chosen date 2. Open Gmail — you should see a draft in the Drafts folder with the event link ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) * **Connection name mismatch** — If you name the Scalekit connection `google-calendar` instead of `googlecalendar`, `get_or_create_connected_account` returns an error. The name in the Dashboard must match the string you pass to `authorize()` exactly. * **Missing OAuth scopes** — If you see a `403 Forbidden` when calling the Calendar or Gmail API, the OAuth app in Google Cloud Console is missing the required scopes. Calendar needs `https://www.googleapis.com/auth/calendar` and Gmail needs `https://www.googleapis.com/auth/gmail.compose`. * **`raise_for_status()` swallowing context** — The default exception message from `requests` truncates the response body. In development, add `print(response.text)` before `raise_for_status()` to see the full error from Google. * **UTC times without timezone info** — Passing a naive `datetime` (without `timezone.utc`) to `isoformat()` produces a string without a `Z` suffix. Google Calendar rejects this with a `400` error. Always construct datetimes with `timezone.utc`. * **`USER_ID` not matching your session** — The script uses a hardcoded `"user_123"`. In production, replace this with the actual user ID from your application’s session. A mismatch means the connected account query returns the wrong user’s tokens. ## Production notes [Section titled “Production notes”](#production-notes) **Timezone handling** — The working-hours check (`WORK_START_HOUR`, `WORK_END_HOUR`) is UTC-only. In production, convert the user’s local timezone and the attendee’s timezone before searching. The `zoneinfo` module (Python 3.9+) handles this without third-party dependencies. **Slot granularity** — The one-hour increment misses 30- and 15-minute openings. For real scheduling, use the busy intervals directly to calculate the gaps between events, then filter by minimum duration. **Multiple calendars** — The `freeBusy` query checks only `primary`. Users who manage work and personal calendars separately will show false availability. Expand the `items` list to include all calendars the user has shared access to. **Draft vs send** — Creating a draft is safer for a first deployment. When you’re confident in the agent’s output quality, switch the Gmail endpoint from `/drafts` to `/messages/send` to make the agent fully autonomous. Add a confirmation step before making this change. **Error recovery** — If `create_event` succeeds but `create_draft` fails, you have an orphaned event with no follow-up email. In production, wrap the two calls in a compensation pattern: track the event ID and delete it if the draft creation fails. **Rate limits** — Google Calendar and Gmail both have per-user quotas. If your agent runs frequently for the same user, add exponential backoff around the `requests.post` calls. ## Next steps [Section titled “Next steps”](#next-steps) * **Add user input** — Replace the hardcoded `ATTENDEE_EMAIL`, `MEETING_TITLE`, and `DURATION_MINUTES` with parameters parsed from natural language using an LLM tool call. * **Build the JavaScript equivalent** — The `agent-auth-examples` repo includes a JavaScript track. Compare the two implementations to see where the patterns converge and where they differ. * **Handle re-authorization** — If a user revokes access, `get_connected_account` returns an inactive account. Add a re-authorization path to recover gracefully instead of crashing. * **Explore other connectors** — The same `authorize()` pattern works for any Scalekit-supported connector: Slack, Notion, Jira. Swap the connector name and replace the Google API calls with the target service’s API. * **Review the Scalekit agent auth quickstart** — For a broader overview of the connected-accounts model, see the [agent auth quickstart](/agentkit/quickstart).

---
# DOCUMENT BOUNDARY
---

# Enforce seat limits with SCIM provisioning

> Block over-quota user creation and alert admins when SCIM pushes users beyond your plan seat limit.

SCIM (System for Cross-domain Identity Management) provisioning runs unsupervised. When a customer’s HR system pushes user #51 to a 50-seat plan, your application will create that user unless you explicitly block it. Scalekit delivers the provisioning events; your application decides whether to act on them. This cookbook shows the two-event pattern that keeps your seat count accurate and tells admins when they need to upgrade their plan. ## SCIM does not enforce seat limits — your app must [Section titled “SCIM does not enforce seat limits — your app must”](#scim-does-not-enforce-seat-limits--your-app-must) Scalekit translates IdP-specific provisioning protocols into a consistent set of webhook events. It does not know your billing model, your seat limits, or which organizations have room for more users. That logic lives in your application. When a user is added in the IdP, Scalekit fires `organization.directory.user_created`. When a user is removed or deactivated, Scalekit fires `organization.directory.user_deleted`. Your webhook handler is the gate between those events and your user table. ## Two webhook events carry the full user lifecycle [Section titled “Two webhook events carry the full user lifecycle”](#two-webhook-events-carry-the-full-user-lifecycle) Both events include the `organization_id`, which lets you look up the seat limit for that specific customer. | Event | When it fires | What to do | | ------------------------------------- | --------------------------------- | ----------------------------------------------------- | | `organization.directory.user_created` | IdP adds or activates a user | Check count — create user or block and notify | | `organization.directory.user_deleted` | IdP removes or deactivates a user | Decrement count — clear any blocked-provisioning flag | ## Track a user count per organization in your database [Section titled “Track a user count per organization in your database”](#track-a-user-count-per-organization-in-your-database) Add a table that stores the provisioned user count and seat limit for each organization. The examples below use plain SQL — translate to your ORM if preferred. db/schema.sql 
```sql
1
CREATE TABLE org_seat_usage (
2
  org_id       TEXT PRIMARY KEY,
3
  seat_limit   INTEGER NOT NULL,
4
  used_seats   INTEGER NOT NULL DEFAULT 0
5
);
```
 Seed this table when you onboard a new customer. Update `seat_limit` whenever the customer upgrades or downgrades their plan. ## Block creation when the count reaches the limit [Section titled “Block creation when the count reaches the limit”](#block-creation-when-the-count-reaches-the-limit) The `user_created` handler increments the seat counter and creates the user only when there is room. Always return `200` to Scalekit — returning an error code causes Scalekit to retry delivery, which does not help when the block is intentional. Verify webhook signatures before processing Always verify that events come from Scalekit before acting on them. An unverified endpoint that mutates your database can be triggered by forged requests. See the [SCIM provisioning quickstart](/directory/scim/quickstart/) for how to verify signatures using the Scalekit SDK. * Node.js webhook-handler.ts 
  ```ts
  1
  import express from 'express'
  2


  3
  const app = express()
  4
  app.use(express.json())
  5


  6
  app.post('/webhooks/scalekit', async (req, res) => {
  7
    const event = req.body
  8


  9
    if (event.type === 'organization.directory.user_created') {
  10
      const orgId = event.organization_id
  11
      const directoryUser = event.data
  12
      let seatLimitReached = false
  13


  14
      // Run the check and insert in a single transaction.
  15
      // FOR UPDATE inside the transaction holds the lock until commit.
  16
      await db.transaction(async (tx) => {
  17
        const usage = await tx.queryOne(
  18
          'SELECT seat_limit, used_seats FROM org_seat_usage WHERE org_id = $1 FOR UPDATE',
  19
          [orgId]
  20
        )
  21


  22
        if (!usage || usage.used_seats >= usage.seat_limit) {
  23
          seatLimitReached = true
  24
          return
  25
        }
  26


  27
        await tx.query(
  28
          'INSERT INTO users (id, org_id, email, name) VALUES ($1, $2, $3, $4)',
  29
          [directoryUser.id, orgId, directoryUser.email, directoryUser.name]
  30
        )
  31
        await tx.query(
  32
          'UPDATE org_seat_usage SET used_seats = used_seats + 1 WHERE org_id = $1',
  33
          [orgId]
  34
        )
  35
      })
  36


  37
      if (seatLimitReached) {
  38
        // Seat limit reached — skip user creation and alert the admin.
  39
        await notifyAdminSeatLimitReached(orgId)
  40
      }
  41
    }
  42


  43
    // Return 200 so Scalekit does not retry this event.
  44
    res.sendStatus(200)
  45
  })
  ```
 * Python webhook\_handler.py 
  ```python
  1
  from flask import Flask, request
  2


  3
  app = Flask(__name__)
  4


  5
  @app.route('/webhooks/scalekit', methods=['POST'])
  6
  def handle_webhook():
  7
      event = request.get_json()
  8


  9
      if event.get('type') == 'organization.directory.user_created':
  10
          org_id = event['organization_id']
  11
          directory_user = event['data']
  12
          seat_limit_reached = False
  13


  14
          # Run the check and insert in a single transaction.
  15
          # FOR UPDATE inside the transaction holds the lock until commit.
  16
          with db.transaction() as tx:
  17
              usage = tx.query_one(
  18
                  'SELECT seat_limit, used_seats FROM org_seat_usage '
  19
                  'WHERE org_id = %s FOR UPDATE',
  20
                  (org_id,)
  21
              )
  22


  23
              if not usage or usage['used_seats'] >= usage['seat_limit']:
  24
                  seat_limit_reached = True
  25
              else:
  26
                  tx.execute(
  27
                      'INSERT INTO users (id, org_id, email, name) VALUES (%s, %s, %s, %s)',
  28
                      (directory_user['id'], org_id,
  29
                       directory_user['email'], directory_user['name'])
  30
                  )
  31
                  tx.execute(
  32
                      'UPDATE org_seat_usage SET used_seats = used_seats + 1 '
  33
                      'WHERE org_id = %s',
  34
                      (org_id,)
  35
                  )
  36


  37
          if seat_limit_reached:
  38
              # Seat limit reached — skip user creation and alert the admin.
  39
              notify_admin_seat_limit_reached(org_id)
  40


  41
      # Return 200 so Scalekit does not retry this event.
  42
      return '', 200
  ```
 * Go webhook\_handler.go 
  ```go
  1
  package main
  2


  3
  import (
  4
    "encoding/json"
  5
    "net/http"
  6
  )
  7


  8
  func webhookHandler(w http.ResponseWriter, r *http.Request) {
  9
    var event map[string]interface{}
  10
    if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
  11
      http.Error(w, "bad request", http.StatusBadRequest)
  12
      return
  13
    }
  14


  15
    if event["type"] == "organization.directory.user_created" {
  16
      orgID := event["organization_id"].(string)
  17
      data := event["data"].(map[string]interface{})
  18
      seatLimitReached := false
  19


  20
      // Run the check and insert in a single transaction.
  21
      // FOR UPDATE inside the transaction holds the lock until commit.
  22
      tx, _ := db.Begin()
  23
      var seatLimit, usedSeats int
  24
      err := tx.QueryRow(
  25
        "SELECT seat_limit, used_seats FROM org_seat_usage WHERE org_id = $1 FOR UPDATE",
  26
        orgID,
  27
      ).Scan(&seatLimit, &usedSeats)
  28


  29
      if err != nil || usedSeats >= seatLimit {
  30
        seatLimitReached = true
  31
        tx.Rollback()
  32
      } else {
  33
        tx.Exec(
  34
          "INSERT INTO users (id, org_id, email, name) VALUES ($1, $2, $3, $4)",
  35
          data["id"], orgID, data["email"], data["name"],
  36
        )
  37
        tx.Exec(
  38
          "UPDATE org_seat_usage SET used_seats = used_seats + 1 WHERE org_id = $1",
  39
          orgID,
  40
        )
  41
        tx.Commit()
  42
      }
  43


  44
      if seatLimitReached {
  45
        // Seat limit reached — skip user creation and alert the admin.
  46
        notifyAdminSeatLimitReached(orgID)
  47
      }
  48
    }
  49


  50
    // Return 200 so Scalekit does not retry this event.
  51
    w.WriteHeader(http.StatusOK)
  52
  }
  ```
 * Java WebhookController.java 
  ```java
  1
  import org.springframework.web.bind.annotation.*;
  2
  import java.util.Map;
  3
  import java.util.concurrent.atomic.AtomicBoolean;
  4


  5
  @RestController
  6
  public class WebhookController {
  7


  8
    @PostMapping("/webhooks/scalekit")
  9
    public ResponseEntity handleWebhook(@RequestBody Map event) {
  10
      if ("organization.directory.user_created".equals(event.get("type"))) {
  11
        String orgId = (String) event.get("organization_id");
  12
        Map directoryUser = (Map) event.get("data");
  13
        AtomicBoolean seatLimitReached = new AtomicBoolean(false);
  14


  15
        // Run the check and insert in a single transaction.
  16
        // FOR UPDATE inside the transaction holds the lock until commit.
  17
        transactionTemplate.execute(status -> {
  18
          OrgSeatUsage usage = db.queryForObject(
  19
            "SELECT seat_limit, used_seats FROM org_seat_usage WHERE org_id = ? FOR UPDATE",
  20
            OrgSeatUsage.class, orgId
  21
          );
  22


  23
          if (usage == null || usage.getUsedSeats() >= usage.getSeatLimit()) {
  24
            seatLimitReached.set(true);
  25
            return null;
  26
          }
  27


  28
          db.update(
  29
            "INSERT INTO users (id, org_id, email, name) VALUES (?, ?, ?, ?)",
  30
            directoryUser.get("id"), orgId,
  31
            directoryUser.get("email"), directoryUser.get("name")
  32
          );
  33
          db.update(
  34
            "UPDATE org_seat_usage SET used_seats = used_seats + 1 WHERE org_id = ?",
  35
            orgId
  36
          );
  37
          return null;
  38
        });
  39


  40
        if (seatLimitReached.get()) {
  41
          // Seat limit reached — skip user creation and alert the admin.
  42
          notifyAdminSeatLimitReached(orgId);
  43
        }
  44
      }
  45


  46
      // Return 200 so Scalekit does not retry this event.
  47
      return ResponseEntity.ok().build();
  48
    }
  49
  }
  ```
 ## Decrement the count when a user is removed [Section titled “Decrement the count when a user is removed”](#decrement-the-count-when-a-user-is-removed) The `user_deleted` handler decreases the seat counter and clears any pending seat-limit notification. This lets the next `user_created` event succeed without manual intervention from your team. * Node.js webhook-handler.ts 
  ```ts
  1
  if (event.type === 'organization.directory.user_deleted') {
  2
    const orgId = event.organization_id
  3
    const directoryUser = event.data
  4


  5
    await db.transaction(async (tx) => {
  6
      // Remove the user and decrement the counter atomically.
  7
      await tx.query('DELETE FROM users WHERE id = $1', [directoryUser.id])
  8
      await tx.query(
  9
        'UPDATE org_seat_usage SET used_seats = GREATEST(used_seats - 1, 0) WHERE org_id = $1',
  10
        [orgId]
  11
      )
  12
      // Clear any pending seat-limit notification so the next user can be provisioned.
  13
      await tx.query(
  14
        "DELETE FROM notifications WHERE org_id = $1 AND type = 'seat_limit_reached'",
  15
        [orgId]
  16
      )
  17
    })
  18
  }
  ```
 * Python webhook\_handler.py 
  ```python
  1
  if event.get('type') == 'organization.directory.user_deleted':
  2
      org_id = event['organization_id']
  3
      directory_user = event['data']
  4


  5
      with db.transaction() as tx:
  6
          # Remove the user and decrement the counter atomically.
  7
          tx.execute('DELETE FROM users WHERE id = %s', (directory_user['id'],))
  8
          tx.execute(
  9
              'UPDATE org_seat_usage SET used_seats = GREATEST(used_seats - 1, 0) '
  10
              'WHERE org_id = %s',
  11
              (org_id,)
  12
          )
  13
          # Clear any pending seat-limit notification so the next user can be provisioned.
  14
          tx.execute(
  15
              "DELETE FROM notifications WHERE org_id = %s AND type = 'seat_limit_reached'",
  16
              (org_id,)
  17
          )
  ```
 * Go webhook\_handler.go 
  ```go
  1
  if event["type"] == "organization.directory.user_deleted" {
  2
    orgID := event["organization_id"].(string)
  3
    data := event["data"].(map[string]interface{})
  4


  5
    tx, _ := db.Begin()
  6
    // Remove the user and decrement the counter atomically.
  7
    tx.Exec("DELETE FROM users WHERE id = $1", data["id"])
  8
    tx.Exec(
  9
      "UPDATE org_seat_usage SET used_seats = GREATEST(used_seats - 1, 0) WHERE org_id = $1",
  10
      orgID,
  11
    )
  12
    // Clear any pending seat-limit notification so the next user can be provisioned.
  13
    tx.Exec(
  14
      "DELETE FROM notifications WHERE org_id = $1 AND type = 'seat_limit_reached'",
  15
      orgID,
  16
    )
  17
    tx.Commit()
  18
  }
  ```
 * Java WebhookController.java 
  ```java
  1
  if ("organization.directory.user_deleted".equals(event.get("type"))) {
  2
    String orgId = (String) event.get("organization_id");
  3
    Map directoryUser = (Map) event.get("data");
  4


  5
    transactionTemplate.execute(status -> {
  6
      // Remove the user and decrement the counter atomically.
  7
      db.update("DELETE FROM users WHERE id = ?", directoryUser.get("id"));
  8
      db.update(
  9
        "UPDATE org_seat_usage SET used_seats = GREATEST(used_seats - 1, 0) WHERE org_id = ?",
  10
        orgId
  11
      );
  12
      // Clear any pending seat-limit notification so the next user can be provisioned.
  13
      db.update(
  14
        "DELETE FROM notifications WHERE org_id = ? AND type = 'seat_limit_reached'",
  15
        orgId
  16
      );
  17
      return null;
  18
    });
  19
  }
  ```
 ## Notify admins without spamming them [Section titled “Notify admins without spamming them”](#notify-admins-without-spamming-them) A new `user_created` event fires for every blocked user. Without deduplication, your admin will receive one email per rejected provisioning attempt. Use an idempotent insert to fire the notification only once per organization until the condition is resolved. db/schema.sql 
```sql
1
CREATE TABLE notifications (
2
  id         SERIAL PRIMARY KEY,
3
  org_id     TEXT NOT NULL,
4
  type       TEXT NOT NULL,
5
  resolved   BOOLEAN NOT NULL DEFAULT FALSE,
6
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
7
  UNIQUE (org_id, type, resolved)
8
);
```
 The `UNIQUE (org_id, type, resolved)` constraint blocks duplicate active notifications. Insert with `ON CONFLICT DO NOTHING` to skip the insert when a notification already exists: * Node.js notify.ts 
  ```ts
  1
  async function notifyAdminSeatLimitReached(orgId: string) {
  2
    // Insert only if no unresolved notification exists for this org.
  3
    const result = await db.query(
  4
      `INSERT INTO notifications (org_id, type, resolved)
  5
       VALUES ($1, 'seat_limit_reached', FALSE)
  6
       ON CONFLICT (org_id, type, resolved) DO NOTHING`,
  7
      [orgId]
  8
    )
  9


  10
    // rowCount is 0 when the conflict was skipped — admin already notified.
  11
    if (result.rowCount === 0) return
  12


  13
    // Send the alert once: email, Slack, in-app — your choice.
  14
    await sendAdminAlert(orgId, 'Seat limit reached — users are not being provisioned.')
  15
  }
  ```
 * Python notify.py 
  ```python
  1
  def notify_admin_seat_limit_reached(org_id: str) -> None:
  2
      # Insert only if no unresolved notification exists for this org.
  3
      result = db.execute(
  4
          """INSERT INTO notifications (org_id, type, resolved)
  5
             VALUES (%s, 'seat_limit_reached', FALSE)
  6
             ON CONFLICT (org_id, type, resolved) DO NOTHING""",
  7
          (org_id,)
  8
      )
  9


  10
      # rowcount is 0 when the conflict was skipped — admin already notified.
  11
      if result.rowcount == 0:
  12
          return
  13


  14
      # Send the alert once: email, Slack, in-app — your choice.
  15
      send_admin_alert(org_id, 'Seat limit reached — users are not being provisioned.')
  ```
 * Go notify.go 
  ```go
  1
  func notifyAdminSeatLimitReached(orgID string) {
  2
    // Insert only if no unresolved notification exists for this org.
  3
    result, _ := db.Exec(
  4
      `INSERT INTO notifications (org_id, type, resolved)
  5
       VALUES ($1, 'seat_limit_reached', FALSE)
  6
       ON CONFLICT (org_id, type, resolved) DO NOTHING`,
  7
      orgID,
  8
    )
  9


  10
    // RowsAffected is 0 when the conflict was skipped — admin already notified.
  11
    rows, _ := result.RowsAffected()
  12
    if rows == 0 {
  13
      return
  14
    }
  15


  16
    // Send the alert once: email, Slack, in-app — your choice.
  17
    sendAdminAlert(orgID, "Seat limit reached — users are not being provisioned.")
  18
  }
  ```
 * Java NotificationService.java 
  ```java
  1
  public void notifyAdminSeatLimitReached(String orgId) {
  2
    // Insert only if no unresolved notification exists for this org.
  3
    int rows = db.update(
  4
      "INSERT INTO notifications (org_id, type, resolved) " +
  5
      "VALUES (?, 'seat_limit_reached', FALSE) " +
  6
      "ON CONFLICT (org_id, type, resolved) DO NOTHING",
  7
      orgId
  8
    );
  9


  10
    // rows is 0 when the conflict was skipped — admin already notified.
  11
    if (rows == 0) return;
  12


  13
    // Send the alert once: email, Slack, in-app — your choice.
  14
    sendAdminAlert(orgId, "Seat limit reached — users are not being provisioned.");
  15
  }
  ```
 When a user is removed and the count drops below the limit, the `user_deleted` handler deletes the notification row. The next blocked `user_created` event will insert a fresh notification and trigger a new alert. *** **Related guides** * [SCIM provisioning quickstart](/directory/scim/quickstart/) — set up webhooks and the Directory API, including signature verification * [Directory webhook events reference](/directory/reference/directory-events/) — full event payload schemas

---
# DOCUMENT BOUNDARY
---

# Search Scalekit docs with ref.tools

> Configure ref.tools MCP to search Scalekit documentation directly from Cursor, Claude Code, or Windsurf without leaving your IDE.

Every time you need to look up a Scalekit API, scope name, or configuration option, you break your flow: open a new tab, search the docs, copy the answer, switch back. With ref.tools configured as an MCP server, your AI coding assistant can search Scalekit documentation inline and return accurate, up-to-date answers without you leaving the editor. Setup takes about two minutes. ## The problem [Section titled “The problem”](#the-problem) AI coding assistants are good at generating code, but they have two failure modes when it comes to third-party docs: * **Hallucination** — The model invents an API that doesn’t exist or gets parameter names wrong because its training data is incomplete * **Stale knowledge** — Even accurate training data goes out of date as SDKs and APIs evolve Both problems get worse when you’re working with a narrowly scoped platform like Scalekit. The model may have seen very little training data about it, and what it did see may be outdated. The standard workaround is to paste docs into the chat manually — which means constant context-switching between your editor and a browser. ref.tools solves both problems by connecting your AI assistant directly to live Scalekit documentation through an MCP tool call. ## Who needs this [Section titled “Who needs this”](#who-needs-this) This cookbook is for you if: * ✅ You use Cursor, Claude Code, Windsurf, or another MCP-compatible AI assistant * ✅ You’re building with Scalekit (auth, SSO, MCP servers, M2M, SCIM) * ✅ You want accurate, up-to-date answers without context-switching to a browser You **don’t** need this if: * ❌ You prefer pasting docs into your chat manually * ❌ Your AI assistant doesn’t support MCP ## The solution [Section titled “The solution”](#the-solution) [ref.tools](https://ref.tools) is a documentation search platform that indexes third-party docs — including Scalekit — and exposes them as an MCP tool called `ref_search_documentation`. Once you add the ref.tools MCP server to your AI assistant, you can prompt it to search Scalekit docs and it will call the tool and return current results directly in chat. The server supports two transports: * **Streamable HTTP** (recommended) — Direct HTTP connection using your API key; lower latency, no local process required * **stdio** (legacy) — Runs a local `npx` process; works with any MCP client that supports stdio ## Set up ref.tools [Section titled “Set up ref.tools”](#set-up-reftools) 1. ### Get your API key [Section titled “Get your API key”](#get-your-api-key) 1. Go to [ref.tools](https://ref.tools) and sign in 2. Search for **Scalekit** to confirm the documentation source is indexed 3. Open the **Quick Install** panel for Scalekit — your API key is pre-filled in the install commands 4. Copy your API key; you’ll use it in the next step 2. ### Add the MCP server to your AI assistant [Section titled “Add the MCP server to your AI assistant”](#add-the-mcp-server-to-your-ai-assistant) Pick your tool and apply the matching configuration. #### Claude Code [Section titled “Claude Code”](#claude-code) Run this command in your terminal to add the MCP server globally across all projects: 
   ```bash
   1
   claude mcp add --transport http ref-context https://api.ref.tools/mcp \
   2
     --header "x-ref-api-key: YOUR_API_KEY"
   ```
 To scope it to a single project instead, add `--scope project` to the command. #### Cursor [Section titled “Cursor”](#cursor) Add the following to `.cursor/mcp.json` in your project root (or via **Settings → MCP**): .cursor/mcp.json 
   ```json
   1
   {
   2
     "ref-context": {
   3
       "type": "http",
   4
       "url": "https://api.ref.tools/mcp?apiKey=YOUR_API_KEY"
   5
     }
   6
   }
   ```
 #### Windsurf [Section titled “Windsurf”](#windsurf) Add the following to `~/.codeium/windsurf/mcp_config.json`: \~/.codeium/windsurf/mcp\_config.json 
   ```json
   1
   {
   2
     "ref-context": {
   3
       "serverUrl": "https://api.ref.tools/mcp?apiKey=YOUR_API_KEY"
   4
     }
   5
   }
   ```
 #### Other (stdio) [Section titled “Other (stdio)”](#other-stdio) For any MCP client that supports stdio, add to your MCP config: mcp.json 
   ```json
   1
   {
   2
     "ref-context": {
   3
       "command": "npx",
   4
       "args": ["ref-tools-mcp@latest"],
   5
       "env": {
   6
         "REF_API_KEY": "YOUR_API_KEY"
   7
       }
   8
     }
   9
   }
   ```
 This requires Node.js installed locally. The `npx` command fetches and runs the server on first use. 3. ### Verify it’s working [Section titled “Verify it’s working”](#verify-its-working) 1. Restart your AI assistant (or use its MCP reload command if available) 2. Open a new chat and send this prompt: 
      ```plaintext
      1
      Use ref to look up how to add OAuth 2.1 authorization to an MCP server with Scalekit
      ```
 3. Your assistant should call the `ref_search_documentation` tool and return results from `docs.scalekit.com` If the tool doesn’t appear, check that you restarted the assistant after saving the config, and that the API key is correct. Keep your API key private Never commit your ref.tools API key to source control. For project-level configs checked into git, pass the key through an environment variable and reference it as `$REF_API_KEY` in your config, or add the config file to `.gitignore`. ## Example searches to try [Section titled “Example searches to try”](#example-searches-to-try) Once ref.tools is connected, use phrases like “use ref to…” or “look up in ref…” to trigger the tool explicitly: * `Use ref to find the Scalekit MCP auth quickstart` * `Look up how to configure SSO with Scalekit` * `Use ref to find Scalekit M2M token documentation` * `Search Scalekit docs for SCIM provisioning setup` * `Use ref to look up Scalekit SDK environment variables` You can also just ask naturally — most assistants will call the tool automatically when the question is about Scalekit. ## Common mistakes [Section titled “Common mistakes”](#common-mistakes) ## Next steps [Section titled “Next steps”](#next-steps) For further setup, authentication options, and available documentation sources, see the links below. * [Add OAuth 2.1 authorization to MCP servers](/authenticate/mcp/quickstart) — the most common thing developers look up using ref * [ref.tools](https://ref.tools) — browse all available documentation sources you can add alongside Scalekit * [M2M authentication overview](/guides/m2m/overview) — machine-to-machine auth patterns frequently searched via ref

---
# DOCUMENT BOUNDARY
---

# Set up AgentKit with your coding agent

> Add Scalekit Agent Auth to your codebase using Claude Code, Codex, GitHub Copilot CLI, Cursor, or any of 40+ coding agents.

Install the authstack plugin into your coding agent and paste one prompt. The agent generates client initialization, connected account management, OAuth authorization, and token handling — no boilerplate required. ## Before you start [Section titled “Before you start”](#before-you-start) * A Scalekit account at [app.scalekit.com](https://app.scalekit.com) * A connector configured under **AgentKit** > **Connections**. The prompt defaults to GitHub (`github-connect`). Name another connector if you want that instead. * Your API credentials from **Developers → API Credentials** ## Pick your coding agent [Section titled “Pick your coding agent”](#pick-your-coding-agent) * Recommended: one command Terminal 
  ```bash
  npx @scalekit-inc/cli setup
  ```
 For repeated use: `npm install -g @scalekit-inc/cli` then `scalekit setup`. The CLI installs the authstack plugin for your editor. Then load the shipped skill `integrate-agentkit`. Complete any browser OAuth prompt for the Scalekit MCP server. Done: the command exits 0 and `integrate-agentkit` is available. Then copy the AgentKit prompt below (or describe your goal naturally). * Per-tool details After the CLI (or if you prefer tool-native flows): * Claude Code / Copilot: marketplace + plugin install is handled by the CLI. * Cursor / Codex: plugins are installed locally by the CLI. * 40+ agents: use the skills option in the CLI or `npx skills add scalekit-inc/authstack --skill integrate-agentkit`. Then copy the AgentKit prompt below. Using a coding agent?Copy AgentKit prompt ## Verify the setup [Section titled “Verify the setup”](#verify-the-setup) 1. **Set environment variables** — copy `SCALEKIT_CLIENT_ID`, `SCALEKIT_CLIENT_SECRET`, and `SCALEKIT_ENVIRONMENT_URL` from the dashboard → **API Credentials**. Done: all three names are set in `.env`. 2. **Trigger the authorization flow** — run the generated example and confirm the browser redirects to the connector’s consent page. Done: the consent page opens. 3. **Fetch a token** — after consent, call the token-fetch function and confirm you receive a valid response. Done: the token-fetch call succeeds. Review generated code before deploying Verify that token validation logic, error handling, and environment variable references match your application’s requirements. The generated code is a foundation, not a finished implementation. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting)

---
# DOCUMENT BOUNDARY
---

# Sync B2B billing with Scalekit and Chargebee

> Map Scalekit organizations to Chargebee customers, run hosted checkout, and keep subscription state in sync via webhooks.

Multi-tenant B2B SaaS apps authenticate users through Scalekit organizations, but bill through Chargebee subscriptions. Those two systems do not share a database. Without an explicit mapping, you end up with duplicate Chargebee customers, subscriptions that never activate after checkout, or feature gates that read stale plan data. This cookbook wires Scalekit organizations and sessions to Chargebee using **org-mode billing**: the organization ID from the access token (`oid`) becomes the billing `referenceId`, Scalekit webhooks provision Chargebee customers, and Chargebee webhooks keep your local subscription table current. You own the routes, schema, and authorization that connect the two systems. ## What you get [Section titled “What you get”](#what-you-get) * Chargebee customers created when Scalekit fires `organization.created` (not on every user signup) * Local org ↔ Chargebee customer mapping keyed by the Scalekit organization ID * Hosted checkout and customer portal via Chargebee hosted pages * Local subscription cache driven by Chargebee webhooks, plus optional eager sync on checkout redirect * Session-scoped authorization so billing APIs only act on the caller’s org (`referenceId === oid`) * Lifecycle hooks for product logic (after customer create, subscription complete/cancel, authorize deny) ## Who needs this [Section titled “Who needs this”](#who-needs-this) This cookbook is for you if: * ✅ You authenticate with Scalekit and use **organizations** (`oid` in access tokens) * ✅ You bill **per organization**, not per individual user * ✅ You use Chargebee hosted checkout or the customer portal * ✅ You maintain a local subscription cache to gate features in your app You **don’t** need this if: * ❌ You bill per user, not per organization * ❌ Scalekit manages your entire product catalog and entitlements (no separate billing system) ## How the integration fits together [Section titled “How the integration fits together”](#how-the-integration-fits-together) Treat the Scalekit **organization ID** as the single billing reference for the tenant. Scalekit authenticates the user and org, your app owns the mapping and local subscription cache, and Chargebee owns catalog, checkout, and billing state. ![Architecture: User logs in via Scalekit, app provisions Chargebee customers and hosted checkout, Chargebee returns checkout success and subscription webhooks, app stores org mapping and subscription cache in local DB](/.netlify/images?url=_astro%2Farchitecture.Cp7V-ALL.png\&w=1568\&h=740\&dpl=6aaa70ad2ea7b40008ad2afd) The integration has four seams: 1. **Provision on org create** — Scalekit `organization.created` webhook → create a Chargebee customer and store the mapping locally. 2. **Authorize every billing call** — session `oid` must match the billing `referenceId` before any Chargebee API call. 3. **Future subscription before checkout** — create a local row with `status: future`, stamp `pendingSubscriptionId` on Chargebee customer metadata, then redirect to hosted checkout. 4. **Reconcile from Chargebee** — subscription webhooks (and an eager sync on checkout redirect) update the local row to `active`, `in_trial`, or cancelled. Screenshots below are from the [reference demo](https://github.com/scalekit-developers/saas-auth-chargebee-example) so you can match each milestone to the product UI. ## Before you start [Section titled “Before you start”](#before-you-start) | Prerequisite | Where to get it | | ---------------------------------------------------------- | -------------------------------------------------------------- | | Scalekit environment with organizations | [Scalekit dashboard](https://app.scalekit.com/) | | OAuth client (`skc_...`) + redirect URI | **API Keys** in the dashboard | | Chargebee sandbox site (Product Catalog 2.0) | Chargebee test site | | Plan **item price** ID (for example `growth-plan-monthly`) | Chargebee **Product Catalog** — reference prices by ID in code | | Test payment gateway (`gw_...`) | Chargebee **Payment Gateways** | | Public tunnel for webhooks | ngrok, LocalTunnel, or similar | ## Step 1: Install packages [Section titled “Step 1: Install packages”](#step-1-install-packages) Install the Scalekit and Chargebee SDKs on the **server** (API routes, webhook handlers). Use whichever package manager you use in your app (`npm`, `pnpm`, or `yarn`); the example below matches the reference app: Terminal 
```bash
1
npm install @scalekit-sdk/node chargebee
```
 Snippets in this cookbook are **Node.js / Next.js App Router**, aligned with the reference app. Scalekit client concepts (token validation, webhook verification, `oid`) apply across SDKs; adapt routes and session storage if you run another stack. Chargebee’s primary SDK surface used here is the Node package. Use your ORM of choice for the local billing tables (the reference app uses Drizzle + SQLite). Keep Chargebee secret API keys server-side only; publishable keys for Chargebee.js may use `NEXT_PUBLIC_*` if you embed payment components. ## Step 2: Configure environment variables [Section titled “Step 2: Configure environment variables”](#step-2-configure-environment-variables) Define these in your server environment (for example `.env` locally and your host’s secrets store in production). | Variable | Purpose | | ----------------------------------------------------------- | ------------------------------------------------------------------ | | `SCALEKIT_ENV_URL` | Scalekit environment URL | | `SCALEKIT_CLIENT_ID` / `SCALEKIT_CLIENT_SECRET` | OAuth client | | `SCALEKIT_REDIRECT_URI` | OAuth callback (for example `http://localhost:3000/auth/callback`) | | `SCALEKIT_WEBHOOK_SECRET` | Verify Scalekit webhook signatures | | `CHARGEBEE_SITE` | Chargebee site subdomain | | `CHARGEBEE_API_KEY` | Full-access API key for your Chargebee site | | `CHARGEBEE_PLAN_ITEM_PRICE_ID` | Default plan item price ID from Product Catalog 2.0 | | `CHARGEBEE_GATEWAY_ACCOUNT_ID` | Optional gateway pin for hosted checkout (`gw_...`) | | `CHARGEBEE_WEBHOOK_USERNAME` / `CHARGEBEE_WEBHOOK_PASSWORD` | Basic Auth for Chargebee webhooks (recommended in production) | | `NEXT_PUBLIC_APP_URL` | App base URL for hosted-page redirects | .env.example 
```bash
1
SCALEKIT_ENV_URL=https://your-env.scalekit.dev
2
SCALEKIT_CLIENT_ID=skc_...
3
SCALEKIT_CLIENT_SECRET=
4
SCALEKIT_REDIRECT_URI=http://localhost:3000/auth/callback
5
SCALEKIT_WEBHOOK_SECRET=
6
CHARGEBEE_SITE=your-site-test
7
CHARGEBEE_API_KEY=
8
CHARGEBEE_PLAN_ITEM_PRICE_ID=growth-plan-monthly
9
CHARGEBEE_GATEWAY_ACCOUNT_ID=gw_your_test_gateway_id
10
CHARGEBEE_WEBHOOK_USERNAME=
11
CHARGEBEE_WEBHOOK_PASSWORD=
12
NEXT_PUBLIC_APP_URL=http://localhost:3000
```
 ## Step 3: Add local schema [Section titled “Step 3: Add local schema”](#step-3-add-local-schema) Add tables for organizations, subscriptions, and optional line items. The organization row holds the Chargebee customer ID; subscriptions are keyed by `reference_id` (the Scalekit org ID from `oid`). Default new subscriptions to `future` so checkout can reconcile before Chargebee assigns a subscription ID. db/schema.sql 
```sql
1
CREATE TABLE organization (
2
  id TEXT PRIMARY KEY,
3
  display_name TEXT,
4
  chargebee_customer_id TEXT UNIQUE,
5
  updated_at INTEGER
6
);
7


8
CREATE TABLE subscription (
9
  id TEXT PRIMARY KEY,
10
  reference_id TEXT NOT NULL,
11
  chargebee_customer_id TEXT,
12
  chargebee_subscription_id TEXT UNIQUE,
13
  status TEXT NOT NULL DEFAULT 'future',
14
  period_start INTEGER,
15
  period_end INTEGER,
16
  trial_start INTEGER,
17
  trial_end INTEGER,
18
  canceled_at INTEGER,
19
  seats INTEGER,
20
  metadata TEXT
21
);
22


23
CREATE TABLE subscription_item (
24
  id TEXT PRIMARY KEY,
25
  subscription_id TEXT NOT NULL REFERENCES subscription(id) ON DELETE CASCADE,
26
  item_price_id TEXT NOT NULL,
27
  item_type TEXT NOT NULL,
28
  quantity INTEGER NOT NULL,
29
  unit_price INTEGER,
30
  amount INTEGER
31
);
```
 Translate to your ORM. Index `reference_id` — webhook handlers and list endpoints query by org ID on every request. **After this step:** migrations applied; empty tables ready for provisioning and checkout. ## Step 4: Initialize clients [Section titled “Step 4: Initialize clients”](#step-4-initialize-clients) Create lazy singletons from environment variables. Never hardcode API keys. lib/scalekit.ts 
```ts
1
import { ScalekitClient } from '@scalekit-sdk/node';
2


3
let scalekitClient: ScalekitClient | null = null;
4


5
export function getScalekitClient(): ScalekitClient {
6
  if (!scalekitClient) {
7
    const envUrl = process.env.SCALEKIT_ENV_URL;
8
    const clientId = process.env.SCALEKIT_CLIENT_ID;
9
    const clientSecret = process.env.SCALEKIT_CLIENT_SECRET;
10
    if (!envUrl || !clientId || !clientSecret) {
11
      throw new Error(
12
        'Set SCALEKIT_ENV_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET.'
13
      );
14
    }
15
    scalekitClient = new ScalekitClient(envUrl, clientId, clientSecret);
16
  }
17
  return scalekitClient;
18
}
```
 lib/chargebee.ts 
```ts
1
import Chargebee from 'chargebee';
2


3
let chargebeeClient: Chargebee | null = null;
4


5
export function getChargebeeClient(): Chargebee {
6
  if (!chargebeeClient) {
7
    const site = process.env.CHARGEBEE_SITE;
8
    const apiKey = process.env.CHARGEBEE_API_KEY;
9
    if (!site || !apiKey) {
10
      throw new Error('Set CHARGEBEE_SITE and CHARGEBEE_API_KEY.');
11
    }
12
    chargebeeClient = new Chargebee({ site, apiKey });
13
  }
14
  return chargebeeClient;
15
}
```
 ## Step 5: Provision Chargebee customers from Scalekit webhooks [Section titled “Step 5: Provision Chargebee customers from Scalekit webhooks”](#step-5-provision-chargebee-customers-from-scalekit-webhooks) Register a Scalekit webhook for `organization.created`, `organization.updated`, and `organization.deleted`. Point it at your public URL (use a tunnel in local dev): 
```text
1
https://your-domain.com/api/webhooks/scalekit
```
 Verify the signature on the **raw request body** before parsing JSON. Verify webhook signatures Never parse the body before verification. Re-serialized JSON breaks signature checks. Read `req.text()` (or the raw buffer), verify, then `JSON.parse`. api/webhooks/scalekit/route.ts 
```ts
1
import { NextRequest, NextResponse } from 'next/server';
2
import { getScalekitClient } from '@/lib/scalekit';
3
import { createOrgCustomer } from '@/lib/billing/create-org-customer';
4
import { cleanupOrganizationBilling } from '@/lib/billing/cleanup-org';
5
import { upsertOrganization } from '@/lib/db/organizations';
6


7
export async function POST(req: NextRequest) {
8
  const rawBody = await req.text();
9
  const secret = process.env.SCALEKIT_WEBHOOK_SECRET;
10
  if (!secret) {
11
    return NextResponse.json({ error: 'Webhook secret not configured' }, { status: 500 });
12
  }
13


14
  const headers: Record = {};
15
  req.headers.forEach((value, key) => {
16
    headers[key.toLowerCase()] = value;
17
  });
18


19
  const client = getScalekitClient();
20
  const isValid = client.verifyWebhookPayload(secret, headers, rawBody);
21
  if (!isValid) {
22
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
23
  }
24


25
  const event = JSON.parse(rawBody);
26
  const organizationId = event.organization_id ?? event.data?.id;
27


28
  if (event.type === 'organization.created' && organizationId) {
29
    await createOrgCustomer({
30
      organizationId,
31
      displayName: event.data?.display_name ?? null,
32
    });
33
  } else if (event.type === 'organization.updated' && organizationId) {
34
    await upsertOrganization({
35
      id: organizationId,
36
      displayName: event.data?.display_name ?? null,
37
    });
38
  } else if (event.type === 'organization.deleted' && organizationId) {
39
    await cleanupOrganizationBilling(organizationId);
40
  }
41


42
  return NextResponse.json({ received: true });
43
}
```
 `createOrgCustomer` upserts the local organization row, creates a Chargebee customer if one does not exist, and stores `organizationId` in Chargebee `meta_data`. Make it idempotent: check the local mapping before calling `customer.create`, and handle races if checkout runs before the webhook finishes. lib/billing/create-org-customer.ts 
```ts
1
const { customer } = await chargebee.customer.create({
2
  company: displayName ?? undefined,
3
  email: email ?? undefined,
4
  preferred_currency_code: 'USD',
5
  meta_data: {
6
    organizationId,
7
    customerType: 'organization',
8
  },
9
});
10


11
await setChargebeeCustomerId(organizationId, customer.id);
```
 Return `2xx` after accepting the event. Scalekit retries on non-2xx responses. The reference app enqueues work with `setImmediate` so the HTTP response is fast; either pattern works if handlers are idempotent. **After this step:** create an organization in Scalekit → local `organization` row and a Chargebee customer with matching `organizationId` metadata appear. In the reference app dashboard, steps 1–3 show **Done** and the org is linked to a Chargebee customer before you open billing: ![Dashboard after sign-in: organization linked to Chargebee customer, subscribe step current](/.netlify/images?url=_astro%2F02-dashboard-org-linked.5twfG6-G.png\&w=3024\&h=1780\&dpl=6aaa70ad2ea7b40008ad2afd) ## Step 6: Read the organization ID from the session [Section titled “Step 6: Read the organization ID from the session”](#step-6-read-the-organization-id-from-the-session) Billing routes need org context from the access token. Validate the token on every request and require the `oid` claim. Do not call `/userinfo` for billing context. lib/auth/require-session.ts 
```ts
1
import { decodeJwt } from 'jose';
2


3
const isValid = await scalekit.validateAccessToken(accessToken);
4
if (!isValid) {
5
  throw new SessionError(401, 'Invalid or expired token');
6
}
7


8
// Safe after validateAccessToken: signature and standard claims already checked.
9
const claims = decodeJwt(accessToken);
10


11
const organizationId = claims.oid as string | undefined;
12
if (!organizationId) {
13
  throw new SessionError(403, 'Organization context required for billing');
14
}
15


16
return {
17
  userId: claims.sub as string,
18
  email: claims.email as string,
19
  organizationId,
20
};
```
 ## Step 7: Authorize billing references [Section titled “Step 7: Authorize billing references”](#step-7-authorize-billing-references) Before any Chargebee API call, confirm the caller’s session org matches the billing reference. Extend with a product hook to deny delinquent orgs without changing Chargebee configuration. lib/auth/authorize-reference.ts 
```ts
1
export type AuthorizeReferenceAction =
2
  | 'create'
3
  | 'update'
4
  | 'cancel'
5
  | 'portal'
6
  | 'list';
7


8
export async function authorizeReference({
9
  userId,
10
  organizationId,
11
  referenceId,
12
  action,
13
}: {
14
  userId: string;
15
  organizationId: string;
16
  referenceId: string;
17
  action: AuthorizeReferenceAction;
18
}): Promise {
19
  if (referenceId !== organizationId) {
20
    return false;
21
  }
22
  // Optional: return false from onAuthorizeReference to deny specific orgs.
23
  return onAuthorizeReference({ userId, organizationId, referenceId, action }) !== false;
24
}
```
 **After this step:** a request with `referenceId` that does not match session `oid` returns `403` before Chargebee is called. ## Step 8: Start hosted checkout with a future subscription [Section titled “Step 8: Start hosted checkout with a future subscription”](#step-8-start-hosted-checkout-with-a-future-subscription) When an org admin clicks **Subscribe**, create a local `future` row first, stamp pending IDs on the Chargebee customer, then call `hostedPage.checkoutNewForItems`. Use **item price IDs** from your Chargebee product catalog. api/subscription/create/route.ts 
```ts
1
const ctx = await requireSession();
2
const referenceId = body.referenceId ?? ctx.organizationId;
3


4
if (
5
  !(await authorizeReference({
6
    userId: ctx.userId,
7
    organizationId: ctx.organizationId,
8
    referenceId,
9
    action: 'create',
10
  }))
11
) {
12
  return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
13
}
14


15
const active = await findActiveByReferenceId(referenceId);
16
if (active) {
17
  return NextResponse.json(
18
    { error: 'An active subscription already exists for this organization' },
19
    { status: 400 }
20
  );
21
}
22


23
const customerId = await getOrCreateCustomerId({
24
  organizationId: referenceId,
25
  email: ctx.email,
26
});
27


28
const localSub = await createFutureSubscription({
29
  referenceId,
30
  chargebeeCustomerId: customerId,
31
});
32


33
await chargebee.customer.update(customerId, {
34
  meta_data: {
35
    pendingSubscriptionId: localSub.id,
36
    pendingReferenceId: referenceId,
37
    organizationId: referenceId,
38
    userId: ctx.userId,
39
  },
40
});
41


42
const result = await chargebee.hostedPage.checkoutNewForItems({
43
  subscription_items: [{ item_price_id: planItemPriceId, quantity: seats }],
44
  customer: { id: customerId },
45
  redirect_url: successRedirect, // includes local subscriptionId for eager sync
46
  cancel_url: absoluteUrl(cancelUrl),
47
  // Optional: pin gateway when Smart Routing cannot auto-select
48
  // ...getHostedCheckoutCardOptions(),
49
});
50


51
return NextResponse.json({ mode: 'hosted', url: result.hosted_page.url });
```
 The `future` row gives your app a stable ID to reconcile against before Chargebee assigns a subscription ID. Reject create when an active subscription already exists for the org. **After this step:** `POST /api/subscription/create` returns `{ mode: 'hosted', url }`; completing checkout in the sandbox creates or updates the Chargebee subscription. In the demo, the billing page lists plans scoped to the session org. **Subscribe** calls your create route, then redirects to Chargebee hosted pages: ![Billing page: Growth plan with Subscribe, integration journey on subscribe step](/.netlify/images?url=_astro%2F03-billing-choose-plan.B2QfAshm.png\&w=3024\&h=1780\&dpl=6aaa70ad2ea7b40008ad2afd) ![Chargebee hosted cart: Growth Plan monthly with 14-day free trial](/.netlify/images?url=_astro%2F04-chargebee-cart.7xKdgMWn.png\&w=3024\&h=1780\&dpl=6aaa70ad2ea7b40008ad2afd) ![Chargebee hosted checkout: account details, payment method, and order summary](/.netlify/images?url=_astro%2F05-chargebee-checkout.D0JjaVN1.png\&w=3024\&h=1780\&dpl=6aaa70ad2ea7b40008ad2afd) ## Step 9: Configure Chargebee webhooks [Section titled “Step 9: Configure Chargebee webhooks”](#step-9-configure-chargebee-webhooks) In the Chargebee dashboard, create a webhook endpoint that points to: 
```text
1
https://your-domain.com/api/webhooks/chargebee
```
 Protect the route with HTTP Basic Auth using `CHARGEBEE_WEBHOOK_USERNAME` and `CHARGEBEE_WEBHOOK_PASSWORD`. Enter the same credentials under Basic Authentication in the Chargebee webhook settings. Subscribe at least to these events (names as in Chargebee / the Node SDK): | Chargebee event | Action | | ------------------------------------------------- | --------------------------------------------------- | | `subscription_created` | Link `chargebee_subscription_id`, set status | | `subscription_activated` / `subscription_started` | Mark `active` or `in_trial`, run entitlements hooks | | `subscription_changed` / `subscription_renewed` | Update plan, seats, period dates | | `subscription_cancelled` | Mark cancelled, revoke entitlements | | `customer_deleted` | Clear local customer mapping | Lookup order when matching a webhook to a local row: 1. `chargebee_subscription_id` on the local row 2. Subscription metadata (if you stamp IDs on the Chargebee subscription) 3. `meta_data.pendingSubscriptionId` on the Chargebee customer 4. `future` row by `reference_id` api/webhooks/chargebee/route.ts 
```ts
1
import { NextRequest, NextResponse } from 'next/server';
2
import {
3
  WebhookAuthenticationError,
4
  basicAuthValidator,
5
} from 'chargebee';
6
import { processChargebeeWebhookEvent } from '@/lib/billing/chargebee-webhook-handler';
7


8
export async function POST(req: NextRequest) {
9
  const username = process.env.CHARGEBEE_WEBHOOK_USERNAME;
10
  const password = process.env.CHARGEBEE_WEBHOOK_PASSWORD;
11


12
  const headers: Record = {};
13
  req.headers.forEach((value, key) => {
14
    headers[key.toLowerCase()] = value;
15
  });
16


17
  if (username && password) {
18
    try {
19
      await basicAuthValidator(
20
        (user, pass) => user === username && pass === password
21
      )(headers);
22
    } catch (err) {
23
      if (err instanceof WebhookAuthenticationError) {
24
        return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
25
      }
26
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
27
    }
28
  }
29


30
  const event = await req.json();
31
  await processChargebeeWebhookEvent(event);
32
  return NextResponse.json({ received: true });
33
}
```
 **After this step:** cancel or change a plan in Chargebee → local subscription status updates without a page refresh loop. After a successful checkout (and webhook or eager sync), the billing UI shows the live plan status — for example **In Trial** — and the journey marks subscribe and webhook sync as **Done**: ![Billing after checkout: In Trial subscription and integration journey complete through webhook sync](/.netlify/images?url=_astro%2F06-billing-subscription-active.bChq_VBK.png\&w=3024\&h=1780\&dpl=6aaa70ad2ea7b40008ad2afd) ## Step 10: Eager-sync on checkout redirect [Section titled “Step 10: Eager-sync on checkout redirect”](#step-10-eager-sync-on-checkout-redirect) Hosted checkout redirects to your success URL before webhooks arrive. Add an eager sync so the billing page shows the subscription immediately. Webhooks remain the source of truth for ongoing changes. api/subscription/success/route.ts 
```ts
1
export async function GET(request: NextRequest) {
2
  const subscriptionId = request.nextUrl.searchParams.get('subscriptionId');
3
  const callbackURL =
4
    request.nextUrl.searchParams.get('callbackURL') ?? '/billing?success=1';
5


6
  if (subscriptionId) {
7
    const local = await findSubscriptionById(subscriptionId);
8
    if (local?.chargebeeSubscriptionId) {
9
      const result = await chargebee.subscription.retrieve(
10
        local.chargebeeSubscriptionId
11
      );
12
      await syncLocalFromChargebeeSubscription(local, result.subscription);
13
    } else if (local?.chargebeeCustomerId) {
14
      // Fallback: list recent subscriptions for the customer and sync the latest
15
      const result = await chargebee.subscription.subscriptionsForCustomer(
16
        local.chargebeeCustomerId,
17
        { limit: 10 }
18
      );
19
      // ...sync latest to local row
20
    }
21
  }
22


23
  return NextResponse.redirect(new URL(callbackURL, request.url));
24
}
```
 Validate `callbackURL` against an allowlist of relative paths so redirects cannot leave your site. ## Define plans [Section titled “Define plans”](#define-plans) Customer provisioning works without a plan catalog in code. To sell plans, map Chargebee **item price IDs** to names, limits, and optional trials. Keep pricing ownership in Chargebee; store entitlement metadata in your app. **Static configuration** (fine for a small catalog): lib/billing/plans.ts 
```ts
1
export type PlanConfig = {
2
  itemPriceId: string;
3
  name: string;
4
  limits: Record;
5
  freeTrial?: { days: number };
6
};
7


8
export const PLANS: PlanConfig[] = [
9
  {
10
    itemPriceId:
11
      process.env.CHARGEBEE_PLAN_ITEM_PRICE_ID ?? 'growth-plan-monthly',
12
    name: 'Growth',
13
    limits: { seats: 25 },
14
    freeTrial: { days: 14 },
15
  },
16
];
```
 **Dynamic configuration (recommended for maintainability):** load plans from your database so marketing and price IDs stay out of source control. Map rows to the same `PlanConfig` shape and fail closed if the query errors. ## Common flows [Section titled “Common flows”](#common-flows) Expand a question when you need that path. Each answer assumes the numbered steps above are in place (schema, webhooks, authorize, hosted checkout). ## Customer customization (optional) [Section titled “Customer customization (optional)”](#customer-customization-optional) Use hooks so product logic stays out of webhook routes. lib/subscription-hooks.ts 
```ts
1
export async function onCustomerCreate(params: {
2
  organizationId: string;
3
  chargebeeCustomerId: string;
4
  displayName?: string | null;
5
}): Promise {
6
  // Analytics, CRM sync, internal tenant linking
7
}
8


9
export async function onSubscriptionComplete(ctx: {
10
  referenceId: string;
11
  subscriptionId: string;
12
  chargebeeSubscriptionId: string;
13
  status: string;
14
}): Promise {
15
  // Enable SSO, flip feature flags, send onboarding email
16
}
17


18
/** Return false to deny billing actions for a reference. */
19
export async function onAuthorizeReference(_params: {
20
  userId: string;
21
  organizationId: string;
22
  referenceId: string;
23
  action: 'create' | 'update' | 'cancel' | 'portal' | 'list';
24
}): Promise {
25
  return true;
26
}
```
 ## Database schema overview [Section titled “Database schema overview”](#database-schema-overview) | Model | Role | | ----------------------- | ---------------------------------------------------------------------------------------------------------- | | **`organization`** | Optional `chargebee_customer_id`; primary key is the Scalekit org ID | | **`subscription`** | `reference_id` (org), Chargebee subscription/customer IDs, status, trial and period dates, seats, metadata | | **`subscription_item`** | Line items (plans, addons, charges) with quantity and pricing details | **Source of truth:** Chargebee owns catalog, invoices, and payment state. Your database is a cache for authorization and UI. After schema changes, migrate your app database the same way you migrate other tables—there is no separate billing CLI. ## Testing [Section titled “Testing”](#testing) Run this validation after wiring both webhook endpoints through a tunnel: 1. **Create an organization** in Scalekit (or fire `organization.created` from the dashboard). 2. **Confirm provisioning** — local `organization` row exists; Chargebee shows a customer with matching `organizationId` metadata. 3. **Sign in** as a user in that org and open your billing page. 4. **Start checkout** — `POST /api/subscription/create` returns `{ mode: 'hosted', url }`. Complete payment with test card `4111 1111 1111 1111`. 5. **Confirm redirect** — browser lands on `/billing?success=1` and the subscription appears without a manual refresh. 6. **Replay a webhook** — send a test `subscription_activated` event from Chargebee and confirm the local row updates. Check session org context 
```bash
1
curl -s http://localhost:3000/api/session \
2
  -H "Cookie: scalekit_session=" | jq '.organizationId'
```
 ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) | Symptom | What to check | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | Orphan org / no Chargebee customer | Scalekit webhook URL and events; `SCALEKIT_WEBHOOK_SECRET`; signature uses **raw** body; handler logs | | Webhooks ignored (Chargebee) | URL path; Basic Auth credentials match env; selected events; tunnel health | | Checkout OK, UI still free tier | Was a `future` row created? Is `pendingSubscriptionId` on the customer? Eager sync route? Chargebee webhooks delivering? | | Status out of date | `chargebee_customer_id` / `chargebee_subscription_id` populated? Event types subscribed? Handler returns 500 on DB failure so Chargebee retries? | | Billing API returns 403 | `referenceId` must equal session `oid`; do not key customers by email alone | | `no_applicable_gateway` on hosted checkout | Add a test gateway; set `CHARGEBEE_GATEWAY_ACCOUNT_ID`; enable Smart Routing | | Checkout succeeds but no redirect | `NEXT_PUBLIC_APP_URL` must be in Chargebee **Allowed redirect domains**; declined cards prevent redirect | | Duplicate Chargebee customers | Race between org webhook and first checkout — make `createOrgCustomer` idempotent | ## Production notes [Section titled “Production notes”](#production-notes) * **Replace SQLite** with Postgres or your production database. Keep the `reference_id` index. * **Rotate webhook secrets** independently for Scalekit and Chargebee. Store them in a secrets manager. * **Make handlers idempotent** — Chargebee retries; upsert by `chargebee_subscription_id`. * **Handle org deletion** — on `organization.deleted`, cancel active Chargebee subscriptions and delete local rows so billing does not continue. * **Do not expose Chargebee secret API keys client-side** — only publishable keys belong in `NEXT_PUBLIC_*` variables. ## Helpful prompts [Section titled “Helpful prompts”](#helpful-prompts) Use these FAQ-style prompts with an AI coding agent (Cursor, Claude Code, Copilot CLI, Codex, and similar). First install the Scalekit authstack plugin for your agent, then paste a prompt from a section below (replace bracketed placeholders with your stack). ### 1. Set up your coding agent [Section titled “1. Set up your coding agent”](#1-set-up-your-coding-agent) Run the Scalekit CLI setup so your agent loads Scalekit auth patterns (reduces hallucinations on sessions, webhooks, and orgs): Terminal 
```bash
1
npx @scalekit-inc/cli setup
```
 For repeated use: Terminal 
```bash
1
npm install -g @scalekit-inc/cli
2
scalekit setup
```
 `setup` with no arguments launches an interactive wizard and detects installed tools. Target one agent explicitly if you prefer: Terminal 
```bash
1
npx @scalekit-inc/cli setup cursor
2
npx @scalekit-inc/cli setup claude
3
npx @scalekit-inc/cli setup codex
4
npx @scalekit-inc/cli setup copilot
```
 See the [Scalekit CLI](/dev-kit/cli/) for flags and what gets installed. After setup, open your agent and use a prompt below. ### 2. Prompts (after setup) [Section titled “2. Prompts (after setup)”](#2-prompts-after-setup) ## Resources [Section titled “Resources”](#resources) * [saas-auth-chargebee-example](https://github.com/scalekit-developers/saas-auth-chargebee-example) — runnable reference app * [External IDs and metadata](/guides/external-ids-and-metadata/) — map Scalekit orgs to internal tenant IDs * [Implement webhooks](https://docs.scalekit.com/authenticate/implement-workflows/implement-webhooks/#_top) — webhook reference

---
# DOCUMENT BOUNDARY
---

# Overview of modelling users and organizations

> Put together a data model for your app's users and organizations

Authenticated users now have access to your app. Now is the time to consider how you’ll structure your data model for users and organizations. This foundational model will serve you well as you implement features such as workspaces, user invitations, role-based access control, and more. Ultimately, this enables your application to fully support B2B use cases. Organizations and Users are the two first-class entities in Scalekit * An **Organization** serves as a dedicated tenant within the application, representing a distinct entity like a company or project. A **User** is an individual account granted access to interact with the application. Typically belong to organization(s). This is a simplified view of the relationship between these two entities ![Data model diagram: a B2B project containing two organizations, each with users showing id, name, email, and role attributes](/.netlify/images?url=_astro%2F1-k.Cosz1iTD.png\&w=2984\&h=3570\&dpl=6aaa70ad2ea7b40008ad2afd) This model makes it easy to implement essential B2B capabilities in your application. ## Flexible user sign-in options for organizations [Section titled “Flexible user sign-in options for organizations”](#flexible-user-sign-in-options-for-organizations) Configure your application to support multiple authentication methods, allowing users to choose their preferred sign-in options. Also, this is crucial for enabling organization administrators to set and enforce specific authentication policies for their users. A primary use case is implementing enterprise Single Sign-On (SSO). This allows your customers to authenticate their users through their organization’s existing Identity Provider (IdP), such as Okta, Google, or Microsoft Entra ID where IdP verifies the user’s identity, granting them secure access to your application. With Scalekit as your authentication platform, administrators can easily enforce authentication policies for their organization’s users. Scalekit handles this enforcement automatically, either applying organization-specific policies or defaulting to your application’s preferred authentication methods on the login page. Configuring these settings is straightforward—simply toggle the desired options in your Scalekit environment through the dashboard or API. #### User records deduplication [Section titled “User records deduplication”](#user-records-deduplication) Regardless of which authentication methods your users choose, Scalekit automatically recognizes users with identical email addresses as the same individual. This eliminates the need for your application to manage multiple user records for the same person and ensures consistent identity recognition across different authentication flows. * Two different Users cannot have the same email address within the same Scalekit environment. * Scalekit automatically consolidates accounts. If a user logs in with an email and password and later uses Google OAuth with the same email, both authentication methods will be linked to the same User record. ## On how users join and leave organizations [Section titled “On how users join and leave organizations”](#on-how-users-join-and-leave-organizations) Control how users join and are provisioned into organizations. Scalekit provides a flexible user provisioning engine to manage the entire user lifecycle. This includes: * Sending and managing user invitations. * Allowing users to discover and join organizations based on their email domain. * Enabling membership in multiple organizations. * Securely de-provisioning users when they leave an organization. These capabilities are built-in, allowing you to deliver a secure and seamless user management experience from day one. ## Enforce user roles and permissions [Section titled “Enforce user roles and permissions”](#enforce-user-roles-and-permissions) While your product may offer a wide range of features, not all users should have identical access or capabilities. For example, in a project management tool, you might allow some users to create projects, while others may have permission only to view them. Managing user permissions can be complex. Scalekit simplifies this by providing the necessary roles and permissions your application needs to make authorization decisions at runtime. When a user [completes the login flow](/authenticate/fsa/complete-login/#decoding-token-claims), the access token issued by Scalekit contains their assigned roles. Your application can inspect this token to control access to different features. By default, Scalekit assigns an `admin` role to the organization creator and a `member` role to all other users, providing a solid foundation for your authorization logic. ## Modify user memberships [Section titled “Modify user memberships”](#modify-user-memberships) Scalekit tracks how users belong to organizations through a `memberships` property on each User object. This property contains an array of membership objects that define the user’s relationship to each organization they belong to. Each membership object includes these key properties: * `organization_id`: Identifies which organization the user belongs to * `roles`: Specifies the user’s roles (assigned by your application) within that organization * `status`: Indicates whether the membership is active, pending invite or invite expired The memberships property enables users to belong to multiple organizations while maintaining clear role and status information for each relationship. 
```json
1
{
2
    "memberships": [
3
      {
4
        "join_time": "2025-06-27T10:57:43.720Z",
5
        "membership_status": "ACTIVE",
6
        "metadata": {
7
          "department": "engineering",
8
          "location": "nyc-office"
9
        },
10
        "name": "string",
11
        "organization_id": "org_1234abcd5678efgh",
12
        "primary_identity_provider": "OKTA",
13
        "roles": [
14
          {
15
            "id": "role_admin",
16
            "name": "Admin"
17
          }
18
        ]
19
      },
20
      {
21
        "join_time": "2025-07-15T14:30:22.451Z",
22
        "membership_status": "ACTIVE",
23
        "metadata": {
24
          "department": "product",
25
          "location": "sf-office"
26
        },
27
        "name": "Jane Smith",
28
        "organization_id": "org_9876zyxw5432vuts",
29
        "primary_identity_provider": "GOOGLE",
30
        "roles": [
31
          {
32
            "id": "role_prod_manager",
33
            "name": "Product Manager"
34
          }
35
        ]
36
      }
37
    ],
38
}
```
 #### Migrating from a 1-to-1 model [Section titled “Migrating from a 1-to-1 model”](#migrating-from-a-1-to-1-model) In a 1-to-1 data model, each user is associated with a single organization. The user’s identity is tied to that specific organization, and they cannot belong to multiple organizations with the same identity. This model is common in applications that were not originally built with multi-tenancy in mind, or where each customer’s data and user base are kept entirely separate. For example, many traditional enterprise software applications like **Slack**, **QuickBooks**, or **Adobe Creative Suite** use this model - each customer purchases their own license and has their own separate user accounts that cannot be shared across different customer organizations. #### Migrating from a 1-to-many model [Section titled “Migrating from a 1-to-many model”](#migrating-from-a-1-to-many-model) If your application allows a single user to be part of multiple organizations, their profile in Scalekit will also be shared across those organizations. While the user’s core profile is consistent, each organization membership stores distinct information like roles, status, and metadata. If you already have a membership table that links users and organizations, you can add the Scalekit `user_id` to that table. When you update a user’s profile, the changes will apply across all their organization memberships. | Aspect | 1-to-1 | 1-to-many | | ------------------- | ------------------------------- | ------------------------------- | | **User belongs to** | One organization | Multiple organizations | | **Email address** | Tied to one org | Unique across environment | | **Authentication** | Per-organization | Across all orgs | | **Example apps** | Adobe Creative, QuickBooks | Slack, GitHub, Figma | | **Scalekit use** | Simpler setup, less flexibility | Full multi-tenancy capabilities |

---
# DOCUMENT BOUNDARY
---

# Set up environment & SDK

> Create your account, install SDK, set up AI tools, and verify your setup to start building with Scalekit

Create a Scalekit account, install the SDK, configure your credentials, and verify the setup. This prepares your environment for adding authentication to your application. Before you begin, create a Scalekit account if you haven’t already. After creating your account, a Scalekit workspace is automatically set up for you with dedicated development and production environments. [Create a Scalekit account](https://app.scalekit.com/ws/signup) 1. ## Get your API credentials [Section titled “Get your API credentials”](#get-your-api-credentials) Scalekit uses the OAuth 2.0 client credentials flow for secure API authentication. Navigate to **Dashboard > Developers > Settings > API credentials** and copy these values: .env 
   ```sh
   SCALEKIT_ENVIRONMENT_URL= # Example: https://acme.scalekit.dev or https://auth.acme.com (if custom domain is set)
   SCALEKIT_CLIENT_ID= # Example: skc_1234567890abcdef
   SCALEKIT_CLIENT_SECRET= # Example: test_abcdef1234567890
   ```
 Your workspace includes two environment URLs: Environment URLs 
   ```md
   https://{your-subdomain}.scalekit.dev  (Development)
   https://{your-subdomain}.scalekit.com  (Production)
   ```
 View your environment URLs in **Dashboard > Developers > Settings**. 2. ## Install and initialize the SDK [Section titled “Install and initialize the SDK”](#install-and-initialize-the-sdk) Choose your preferred language and install the Scalekit SDK: * Node.js 
     ```bash
     npm install @scalekit-sdk/node
     ```
 * Python 
     ```sh
     pip install scalekit-sdk-python
     ```
 * Go 
     ```sh
     go get -u github.com/scalekit-inc/scalekit-sdk-go
     ```
 * Java 
     ```groovy
     /* Gradle users - add the following to your dependencies in build file */
     implementation "com.scalekit:scalekit-sdk-java:2.1.3"
     ```
 
     ```xml
     
     
         com.scalekit
         scalekit-sdk-java
         2.1.3
     
     ```
 After installation, initialize the SDK with your credentials: * Node.js Initialize SDK 
     ```js
     1
     import { Scalekit } from '@scalekit-sdk/node';
     2


     3
     // Initialize the Scalekit client with your credentials
     4
     const scalekit = new Scalekit(
     5
       process.env.SCALEKIT_ENVIRONMENT_URL,
     6
       process.env.SCALEKIT_CLIENT_ID,
     7
       process.env.SCALEKIT_CLIENT_SECRET
     8
     );
     ```
 * Python Initialize SDK 
     ```python
     1
     from scalekit import ScalekitClient
     2
     import os
     3


     4
     # Initialize the Scalekit client with your credentials
     5
     scalekit_client = ScalekitClient(
     6
       env_url=os.getenv('SCALEKIT_ENVIRONMENT_URL'),
     7
       client_id=os.getenv('SCALEKIT_CLIENT_ID'),
     8
       client_secret=os.getenv('SCALEKIT_CLIENT_SECRET')
     9
     )
     ```
 * Go Initialize SDK 
     ```go
     1
     import (
     2
       "os"
     3
       "github.com/scalekit-inc/scalekit-sdk-go"
     4
     )
     5


     6
     // Initialize the Scalekit client with your credentials
     7
     scalekitClient := scalekit.NewScalekitClient(
     8
       os.Getenv("SCALEKIT_ENVIRONMENT_URL"),
     9
       os.Getenv("SCALEKIT_CLIENT_ID"),
     10
       os.Getenv("SCALEKIT_CLIENT_SECRET"),
     11
     )
     ```
 * Java Initialize SDK 
     ```java
     1
     import com.scalekit.ScalekitClient;
     2


     3
     // Initialize the Scalekit client with your credentials
     4
     ScalekitClient scalekitClient = new ScalekitClient(
     5
       System.getenv("SCALEKIT_ENVIRONMENT_URL"),
     6
       System.getenv("SCALEKIT_CLIENT_ID"),
     7
       System.getenv("SCALEKIT_CLIENT_SECRET")
     8
     );
     ```
 3. ## Verify your setup [Section titled “Verify your setup”](#verify-your-setup) Test your configuration by listing organizations in your workspace. This confirms your credentials work correctly. * cURL Authenticate with client credentials 
     ```bash
     # Get an access token
     curl https:///oauth/token \
       -X POST \
       -H 'Content-Type: application/x-www-form-urlencoded' \
       -d 'client_id=' \
       -d 'client_secret=' \
       -d 'grant_type=client_credentials'
     ```
 This returns an access token: 
     ```json
     {
       "access_token": "eyJhbGciOiJSUzI1NiIsImInR5cCI6IkpXVCJ9...",
       "token_type": "Bearer",
       "expires_in": 86399,
       "scope": "openid"
     }
     ```
 Use the token to access the Scalekit API List organizations 
     ```sh
     curl -L '/api/v1/organizations?page_size=5' \
       -H 'Authorization: Bearer '
     ```
 * Node.js Create a file `verify.js` with the following code: verify.js 
     ```javascript
     import { ScalekitClient } from '@scalekit-sdk/node';


     const scalekit = new ScalekitClient(
       process.env.SCALEKIT_ENVIRONMENT_URL,
       process.env.SCALEKIT_CLIENT_ID,
       process.env.SCALEKIT_CLIENT_SECRET,
     );


     const { organizations } = await scalekit.organization.listOrganization({
       pageSize: 5,
     });


     console.log(`Name of the first organization: ${organizations[0].display_name}`);
     ```
 Run the verification script: Run verification 
     ```bash
     node verify.js
     ```
 * Python Create a file `verify.py` with the following code: verify.py 
     ```python
     from scalekit import ScalekitClient
     import os


     # Initialize the SDK client
     scalekit_client = ScalekitClient(
       os.getenv('SCALEKIT_ENVIRONMENT_URL'),
       os.getenv('SCALEKIT_CLIENT_ID'),
       os.getenv('SCALEKIT_CLIENT_SECRET')
     )


     org_list = scalekit_client.organization.list_organizations(page_size=5)


     print(f'Name of the first organization: {org_list[0].display_name}')
     ```
 Run the verification script: Run verification 
     ```bash
     python verify.py
     ```
 * Go Create a file `verify.go` with the following code: verify.go 
     ```go
     package main


     import (
       "context"
       "fmt"
       "os"
       "github.com/scalekit-inc/scalekit-sdk-go"
     )


     func main() {
       ctx := context.Background()


       scalekitClient := scalekit.NewScalekitClient(
         os.Getenv("SCALEKIT_ENVIRONMENT_URL"),
         os.Getenv("SCALEKIT_CLIENT_ID"),
         os.Getenv("SCALEKIT_CLIENT_SECRET"),
       )


       organizations, err := scalekitClient.Organization.ListOrganizations(ctx, &scalekit.ListOrganizationsParams{
         PageSize: 5,
       })


       if err != nil {
         panic(err)
       }


       fmt.Printf("Name of the first organization: %s\n", organizations[0].DisplayName)
     }
     ```
 * Java Create a file `Verify.java` with the following code: Verify.java 
     ```java
     import com.scalekit.ScalekitClient;
     import com.scalekit.models.ListOrganizationsResponse;


     public class Verify {
       public static void main(String[] args) {
         ScalekitClient scalekitClient = new ScalekitClient(
           System.getenv("SCALEKIT_ENVIRONMENT_URL"),
           System.getenv("SCALEKIT_CLIENT_ID"),
           System.getenv("SCALEKIT_CLIENT_SECRET")
         );


         ListOrganizationsResponse organizations = scalekitClient.organizations().listOrganizations(5, "");
         System.out.println("Name of the first organization: " + organizations.getOrganizations()[0].getDisplayName());
       }
     }
     ```
 If you see organization data, your setup is complete! You’re now ready to implement authentication in your application. ## Set up Scalekit MCP Server Optional [Section titled “Set up Scalekit MCP Server ”](#set-up-scalekit-mcp-server-) Scalekit’s Model Context Protocol (MCP) server connects your AI coding assistants to Scalekit. Manage environments, organizations, users, and authentication through natural language queries in your MCP client. The MCP server provides AI assistants with tools for environment management, organization and user management, authentication connection setup, role administration, and admin portal access. It uses OAuth 2.1 authentication to securely connect your AI tools to your Scalekit workspace. ### Configure your MCP client [Section titled “Configure your MCP client”](#configure-your-mcp-client) Use the most common client configs below. For the full list of supported MCP hosts and editor setups, see the [Scalekit MCP server guide](/dev-kit/ai-assisted-development/scalekit-mcp-server/). * Claude Code Run this command in your terminal: Terminal 
  ```bash
  1
  claude mcp add --transport http scalekit https://mcp.scalekit.com/
  ```
 * Cursor Edit `~/.cursor/mcp.json`, or open **Cursor Settings → MCP → Add New Global MCP Server** and paste the config: \~/.cursor/mcp.json 
  ```json
  {
    "mcpServers": {
      "scalekit": {
        "url": "https://mcp.scalekit.com/"
      }
    }
  }
  ```
 * Codex Run this command in your terminal: Terminal 
  ```bash
  1
  codex mcp add scalekit --url https://mcp.scalekit.com/
  ```
 * OpenCode Edit `opencode.json` in your project root: opencode.json 
  ```json
  {
    "mcp": {
      "scalekit": {
        "type": "remote",
        "url": "https://mcp.scalekit.com/"
      }
    }
  }
  ```
 After configuration, your MCP client will initiate an OAuth authorization workflow to securely connect to Scalekit’s MCP server. ## Configure code editors for Scalekit documentation [Section titled “Configure code editors for Scalekit documentation”](#configure-code-editors-for-scalekit-documentation) In-code editor chat features are powered by models that understand your codebase and project context. These models search the web for relevant information to help you. However, they may not always have the latest information. Follow the instructions below to configure your code editors to explicitly index for up-to-date information. ### Set up Cursor [Section titled “Set up Cursor”](#set-up-cursor) [Play](https://youtube.com/watch?v=oMMG1k_9fmU) To enable Cursor to access up-to-date Scalekit documentation: 1. Open Cursor settings (Cmd/Ctrl + ,) 2. Navigate to **Indexing & Docs** section 3. Click on **Add** 4. Add `https://docs.scalekit.com/llms-full.txt` to the indexable URLs 5. Click on **Save** Once configured, use `@Scalekit Docs` in your chat to ask questions about Scalekit features, APIs, and integration guides. Cursor will search the latest documentation to provide accurate, up-to-date answers. ### Use Windsurf [Section titled “Use Windsurf”](#use-windsurf) ![Windsurf editor with the Cascade chat panel answering a question using indexed Scalekit documentation](/.netlify/images?url=_astro%2Fwindsurf.CfsQQlGb.png\&w=1357\&h=818\&dpl=6aaa70ad2ea7b40008ad2afd) Windsurf enables `@docs` mentions within the Cascade chat to search for the best answers to your questions. * Full Documentation 
  ```plaintext
  1
  @docs:https://docs.scalekit.com/llms-full.txt
  2
  
  ```
 Costs more tokens. * Specific Section 
  ```plaintext
  1
  @docs:https://docs.scalekit.com/your-specific-section-or-file
  2
  
  ```
 Costs less tokens. * Let AI decide 
  ```plaintext
  1
  @docs:https://docs.scalekit.com/llms.txt
  2
  
  ```
 Costs tokens as per the model decisions. ## Use a coding agent [Section titled “Use a coding agent”](#use-a-coding-agent) Using a coding agent?Copy SaaSKit prompt Change the skill name if you are adding a different product: | Product | Example prompt | | -------------------- | -------------------------------------------------------- | | AgentKit | `Use integrate-agentkit to connect this agent to Gmail.` | | MCP authentication | `Use add-mcp-oauth to add OAuth 2.1 to this MCP server.` | | Single sign-on (SSO) | `Use implement-sso to add SAML and OIDC SSO.` | | SCIM | `Use implement-scim to add user provisioning.` | See the [Build with AI guide](/dev-kit/build-with-ai/) for the full setup. [Play](https://youtube.com/watch?v=ZDAI32I6s-I)

---
# DOCUMENT BOUNDARY
---

# Complete login with code exchange

> Process authentication callbacks and handle redirect flows after users authenticate with Scalekit

Once users have successfully verified their identity using their chosen login method, Scalekit will have gathered the necessary user information for your app to complete the login process. However, your app must provide a callback endpoint where Scalekit can exchange an authorization code to return your app the user details. 1. ## Validate the `state` parameter recommended [Section titled “Validate the state parameter ”](#validate-the-state-parameter-) Before exchanging the authorization code, your application must validate the `state` parameter returned by Scalekit. Compare it with the value you stored in the user’s session before redirecting them. This critical step prevents Cross-Site Request Forgery (CSRF) attacks, ensuring the authentication response corresponds to a request initiated by the same user. * Node.js Validate state in Express.js 
     ```javascript
     1
     const { state } = req.query;
     2


     3
     // Assumes you are using a session middleware like express-session
     4
     const storedState = req.session.oauthState;
     5
     delete req.session.oauthState; // State should be used only once
     6


     7
     if (!state || state !== storedState) {
     8
       console.error('Invalid state parameter');
     9
       return res.redirect('/login?error=invalid_state');
     10
     }
     ```
 * Python Validate state in Flask 
     ```python
     1
     from flask import session, request, redirect
     2


     3
     state = request.args.get('state')
     4


     5
     # Retrieve and remove stored state from session
     6
     stored_state = session.pop('oauth_state', None)
     7


     8
     if not state or state != stored_state:
     9
         print('Invalid state parameter')
     10
         return redirect('/login?error=invalid_state')
     ```
 * Go Validate state in Gin 
     ```go
     1
     stateParam := c.Query("state")
     2


     3
     // Assumes you are using a session library like gin-contrib/sessions
     4
     session := sessions.Default(c)
     5
     storedState := session.Get("oauth_state")
     6
     session.Delete("oauth_state") // State should be used only once
     7
     session.Save()
     8


     9
     if stateParam == "" || stateParam != storedState {
     10
         log.Println("Invalid state parameter")
     11
         c.Redirect(http.StatusFound, "/login?error=invalid_state")
     12
         return
     13
     }
     ```
 * Java Validate state in Spring 
     ```java
     1
     // Assumes HttpSession is injected into your controller method
     2
     String storedState = (String) session.getAttribute("oauth_state");
     3
     session.removeAttribute("oauth_state"); // State should be used only once
     4


     5
     if (state == null || !state.equals(storedState)) {
     6
         System.err.println("Invalid state parameter");
     7
         return new RedirectView("/login?error=invalid_state");
     8
     }
     ```
 2. ## Exchange authorization code for tokens [Section titled “Exchange authorization code for tokens”](#exchange-authorization-code-for-tokens) Once the `state` is validated, your app can safely exchange the authorization code for tokens. The Scalekit SDK simplifies this process with the `authenticateWithCode` method, which handles the secure server-to-server request. * Node.js Express.js callback handler 
     ```javascript
     1
     app.get('/auth/callback', async (req, res) => {
     2
       const { code, error, error_description, state } = req.query;
     3


     4
       //  Add state validation here (see previous step)
     5


     6
       // Handle errors first
     7
       if (error) {
     8
         console.error('Authentication error:', error);
     9
         return res.redirect('/login?error=auth_failed');
     10
       }
     11


     12
       if (!code) {
     13
         return res.redirect('/login?error=missing_code');
     14
       }
     15


     16
       try {
     17
         // Exchange code for user data
     18
         const authResult = await scalekit.authenticateWithCode(
     19
           code,
     20
           'https://yourapp.com/auth/callback'
     21
         );
     22


     23
         const { user, accessToken, refreshToken } = authResult;
     24


     25
         // TODO: Store user session (next guide covers this)
     26
         // req.session.user = user;
     27


     28
         res.redirect('/dashboard');
     29


     30
       } catch (error) {
     31
         console.error('Token exchange failed:', error);
     32
         res.redirect('/login?error=exchange_failed');
     33
       }
     34
     });
     ```
 * Python Flask callback handler 
     ```python
     1
     @app.route('/auth/callback')
     2
     def auth_callback():
     3
         code = request.args.get('code')
     4
         error = request.args.get('error')
     5
         state = request.args.get('state')
     6


     7
         # TODO: Add state validation here (see previous step)
     8


     9
         # Handle errors first
     10
         if error:
     11
             print(f'Authentication error: {error}')
     12
             return redirect('/login?error=auth_failed')
     13


     14
         if not code:
     15
             return redirect('/login?error=missing_code')
     16


     17
         try:
     18
             # Exchange code for user data
     19
             options = CodeAuthenticationOptions()
     20
             auth_result = scalekit.authenticate_with_code(
     21
                 code,
     22
                 'https://yourapp.com/auth/callback',
     23
                 options
     24
             )
     25


     26
             user = auth_result.user
     27
             # access_token = auth_result.access_token
     28
             # refresh_token = auth_result.refresh_token
     29


     30
             # TODO: Store user session (next guide covers this)
     31
             # session['user'] = user
     32


     33
             return redirect('/dashboard')
     34


     35
         except Exception as e:
     36
             print(f'Token exchange failed: {e}')
     37
             return redirect('/login?error=exchange_failed')
     ```
 * Go Gin callback handler 
     ```go
     1
     func authCallbackHandler(c *gin.Context) {
     2
         code := c.Query("code")
     3
         errorParam := c.Query("error")
     4
         stateParam := c.Query("state")
     5


     6
         // TODO: Add state validation here (see previous step)
     7


     8
         // Handle errors first
     9
         if errorParam != "" {
     10
             log.Printf("Authentication error: %s", errorParam)
     11
             c.Redirect(http.StatusFound, "/login?error=auth_failed")
     12
             return
     13
         }
     14


     15
         if code == "" {
     16
             c.Redirect(http.StatusFound, "/login?error=missing_code")
     17
             return
     18
         }
     19


     20
         // Exchange code for user data
     21
         options := scalekit.AuthenticationOptions{}
     22
         authResult, err := scalekitClient.AuthenticateWithCode(
     23
             c.Request.Context(), code,
     24
             "https://yourapp.com/auth/callback",
     25
             options,
     26
         )
     27


     28
         if err != nil {
     29
             log.Printf("Token exchange failed: %v", err)
     30
             c.Redirect(http.StatusFound, "/login?error=exchange_failed")
     31
             return
     32
         }
     33


     34
         user := authResult.User
     35
         // accessToken := authResult.AccessToken
     36
         // refreshToken := authResult.RefreshToken
     37


     38
         // TODO: Store user session (next guide covers this)
     39
         // session.Set("user", user)
     40


     41
         c.Redirect(http.StatusFound, "/dashboard")
     42
     }
     ```
 * Java Spring callback handler 
     ```java
     1
     @GetMapping("/auth/callback")
     2
     public Object authCallback(
     3
         @RequestParam(required = false) String code,
     4
         @RequestParam(required = false) String error,
     5
         @RequestParam(required = false) String state,
     6
         HttpSession session
     7
     ) {
     8
         // TODO: Add state validation here (see previous step)
     9


     10
         // Handle errors first
     11
         if (error != null) {
     12
             System.err.println("Authentication error: " + error);
     13
             return new RedirectView("/login?error=auth_failed");
     14
         }
     15


     16
         if (code == null) {
     17
             return new RedirectView("/login?error=missing_code");
     18
         }
     19


     20
         try {
     21
             // Exchange code for user data
     22
             AuthenticationOptions options = new AuthenticationOptions();
     23
             AuthenticationResponse authResult = scalekit
     24
                 .authentication()
     25
                 .authenticateWithCode(code, "https://yourapp.com/auth/callback", options);
     26


     27
             var user = authResult.getIdTokenClaims();
     28
             // String accessToken = authResult.getAccessToken();
     29
             // String refreshToken = authResult.getRefreshToken();
     30


     31
             // TODO: Store user session (next guide covers this)
     32
             // session.setAttribute("user", user);
     33


     34
             return new RedirectView("/dashboard");
     35


     36
         } catch (Exception e) {
     37
             System.err.println("Token exchange failed: " + e.getMessage());
     38
             return new RedirectView("/login?error=exchange_failed");
     39
         }
     40
     }
     ```
 The authorization `code` can be redeemed only once and expires in approx \~10 minutes. Reuse or replay attempts typically return errors like `invalid_grant`. If this occurs, start a new login flow to obtain a fresh `code` and `state`. The `authResult` object returned contains: 
   ```js
     {
       user: {
         email: "john.doe@example.com",
         emailVerified: true,
         givenName: "John",
         name: "John Doe",
         id: "usr_74599896446906854"
       },
       idToken: "eyJhbGciO..", // Decode for full user details


       accessToken: "eyJhbGciOi..",
       refreshToken: "rt_8f7d6e5c4b3a2d1e0f9g8h7i6j..",
       expiresIn: 299 // in seconds
     }
   ```
 | Key | Description | | -------------- | ------------------------------------------------------------- | | `user` | Common user details with email, name, and verification status | | `idToken` | JWT containing verified full user identity claims | | `accessToken` | Short-lived token that determines current access | | `refreshToken` | Long-lived token to obtain new access tokens | 3. ## Decoding token claims [Section titled “Decoding token claims”](#decoding-token-claims) The `idToken` and `accessToken` are JSON Web Tokens (JWT) that contain user claims. These tokens can be decoded to retrieve comprehensive user and access information. * Node.js Decode ID token 
     ```javascript
     1
     // Use a library like 'jsonwebtoken'
     2
     const jwt = require('jsonwebtoken');
     3


     4
     // The idToken from the authResult object
     5
     const { idToken } = authResult;
     6


     7
     // Decode the token without verifying its signature
     8
     const decoded = jwt.decode(idToken);
     9


     10
     console.log('Decoded claims:', decoded);
     ```
 * Python Decode ID token 
     ```python
     1
     # Use a library like 'PyJWT'
     2
     import jwt
     3


     4
     # The id_token from the auth_result object
     5
     id_token = auth_result.id_token
     6


     7
     # Decode the token without verifying its signature
     8
     decoded = jwt.decode(id_token, options={"verify_signature": False})
     9
     print(f'Decoded claims: {decoded}')
     ```
 * Go Decode ID token 
     ```go
     1
     // Use a library like 'github.com/golang-jwt/jwt/v5'
     2
     import (
     3
       "fmt"
     4
       "github.com/golang-jwt/jwt/v5"
     5
     )
     6


     7
     // The IdToken from the authResult object
     8
     idToken := authResult.IdToken
     9
     token, _, err := new(jwt.Parser).ParseUnverified(idToken, jwt.MapClaims{})
     10
     if err != nil {
     11
       fmt.Printf("Error parsing token: %v\n", err)
     12
       return
     13
     }
     14


     15
     if claims, ok := token.Claims.(jwt.MapClaims); ok {
     16
       fmt.Printf("Decoded claims: %+v\n", claims)
     17
     }
     ```
 * Java Decode ID token 
     ```java
     1
     // Use a library like 'com.auth0:java-jwt'
     2
     import com.auth0.jwt.JWT;
     3
     import com.auth0.jwt.interfaces.DecodedJWT;
     4
     import com.auth0.jwt.interfaces.Claim;
     5
     import com.auth0.jwt.exceptions.JWTDecodeException;
     6
     import java.util.Map;
     7


     8
     try {
     9
         // The idToken from the authResult object
     10
         String idToken = authResult.getIdToken();
     11


     12
         // Decode the token without verifying its signature
     13
         DecodedJWT decodedJwt = JWT.decode(idToken);
     14
         Map claims = decodedJwt.getClaims();
     15


     16
         System.out.println("Decoded claims: " + claims);
     17
     } catch (JWTDecodeException exception){
     18
         // Invalid token
     19
         System.err.println("Failed to decode ID token: " + exception.getMessage());
     20
     }
     ```
 The decoded token claims contain: * Decoded ID token ID token decoded 
     ```json
     1
     {
     2
       "iss": "https://scalekit-z44iroqaaada-dev.scalekit.cloud", // Issuer: Scalekit environment URL (must match your environment)
     3
       "aud": ["skc_58327482062864390"], // Audience: Your client ID (must match for validation)
     4
       "azp": "skc_58327482062864390", // Authorized party: Usually same as aud
     5
       "sub": "usr_63261014140912135", // Subject: User's unique identifier
     6
       "oid": "org_59615193906282635", // Organization ID: User's organization
     7
       "exp": 1742975822, // Expiration: Unix timestamp (validate token hasn't expired)
     8
       "iat": 1742974022, // Issued at: Unix timestamp when token was issued
     9
       "at_hash": "ec_jU2ZKpFelCKLTRWiRsg", // Access token hash: For token binding validation
     10
       "c_hash": "6wMreK9kWQQY6O5R0CiiYg", // Authorization code hash: For code binding validation
     11
       "amr": ["conn_123"], // Authentication method reference: Connection ID used for auth
     12
       "email": "john.doe@example.com", // User's email address
     13
       "email_verified": true, // Email verification status
     14
       "name": "John Doe", // User's full name (optional)
     15
       "given_name": "John", // User's first name (optional)
     16
       "family_name": "Doe", // User's last name (optional)
     17
       "picture": "https://...", // Profile picture URL (optional)
     18
       "locale": "en", // User's locale preference (optional)
     19
       "sid": "ses_65274187031249433", // Session ID: Links token to user session
     20
       "client_id": "skc_58327482062864390", // Client ID: Your application identifier
     21
       "xoid": "ext_org_123", // External organization ID (if mapped)
     22
     }
     ```
 * Decoded access token Decoded access token 
     ```json
     1
     {
     2
         "iss": "https://login.devramp.ai", // Issuer: Scalekit environment URL (must match your environment)
     3
         "aud": ["prd_skc_7848964512134X699"], // Audience: Your client ID (must match for validation)
     4
         "sub": "usr_8967800122X995270", // Subject: User's unique identifier
     5
         "oid": "org_89678001X21929734", // Organization ID: User's organization
     6
         "exp": 1758265247, // Expiration: Unix timestamp (validate token hasn't expired)
     7
         "iat": 1758264947, // Issued at: Unix timestamp when token was issued
     8
         "nbf": 1758264947, // Not before: Unix timestamp (token valid from this time)
     9
         "jti": "tkn_90928731115292X63", // JWT ID: Unique token identifier
     10
         "sid": "ses_90928729571723X24", // Session ID: Links token to user session
     11
         "client_id": "prd_skc_7848964512134X699", // Client ID: Your application identifier
     12
         "roles": ["admin"], // Roles: User roles within organization (optional, for authorization)
     13
         "permissions": ["workspace_data:write", "workspace_data:read"], // Permissions: resource:action format (optional, for granular access control)
     14
         "scope": "openid profile email", // OAuth scopes granted (optional)
     15
         "xoid": "ext_org_123", // External organization ID (if mapped)
     16
         "xuid": "ext_usr_456" // External user ID (if mapped)
     17
     }
     ```
 4. ## Verifying access tokens optional [Section titled “Verifying access tokens ”](#verifying-access-tokens-) The Scalekit SDK provides methods to validate tokens automatically. When you use the SDK’s `validateAccessToken` method, it: 1. Verifies the token signature using Scalekit’s public keys 2. Checks the token hasn’t expired (`exp` claim) 3. Validates the issuer (`iss` claim) matches your environment 4. Ensures the audience (`aud` claim) matches your client ID If you need to manually verify tokens, fetch the public signing keys from the JSON Web Key Set (JWKS) endpoint: JWKS endpoint 
   ```sh
   1
   https:///keys
   ```
 For example, if your Scalekit Environment URL is `https://your-environment.scalekit.com`, the keys can be found at `https://your-environment.scalekit.com/keys`. An `IdToken` contains comprehensive profile information about the user. You can save this in your database for app use cases, using [your own identifier](/fsa/guides/organization-identifiers/). Now, let’s utilize *access and refresh tokens* to manage user access and maintain active sessions. ## Common login scenarios [Section titled “Common login scenarios”](#common-login-scenarios) Customize the login flow by passing different parameters when creating the authorization URL. These scenarios help you route users to specific organizations, force re-authentication, or direct users to signup. Include state in production code The routing examples below omit `state` so the parameter focus stays visible. In production, always set `options.state` to a cryptographically random value, store it server-side before redirecting, and validate it on callback. See [Validate the `state` parameter](#validate-the-state-parameter-) above and [Initiate user login](/authenticate/fsa/implement-login/).

---
# DOCUMENT BOUNDARY
---

# Initiate user signup or login

> Create authorization URLs and redirect users to Scalekit's hosted login page

Login initiation begins your authentication flow. You redirect users to Scalekit’s hosted login page by creating an authorization URL with appropriate parameters. When users visit this URL, Scalekit’s authorization server validates the request, displays the login interface, and handles authentication through your configured connection methods (SSO, social providers, Magic Link or Email OTP). Authorization URL format 
```sh
/oauth/authorize?
  response_type=code& # always `code` for authorization code flow
  client_id=& # Dashboard > Developers > Settings > API Credentials
  redirect_uri=& # Dashboard > Authentication > Redirect URLs > Allowed Callback URLs
  scope=openid+profile+email+offline_access& # Permissions requested. Include `offline_access` for refresh tokens
  state= # prevent CSRF attacks
```
 The authorization request includes several parameters that control authentication behavior: * **Required parameters** ensure Scalekit can identify your application and return the user securely * **Optional parameters** enable organization routing and pre-populate fields * **Security parameters** prevent unauthorized access attempts Understand each parameter and how it controls the authorization flow: | Query parameter | Description | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `response_type` | Set to `code` for authorization code flow Required Indicates the expected response type | | `client_id` | Your application’s public identifier from the dashboard Required Scalekit uses this to identify and validate your application | | `redirect_uri` | Your application’s callback URL where Scalekit returns the authorization code Required Must be registered in your dashboard settings | | `scope` | Space-separated list of permissions Required Always include `openid profile email`. Add `offline_access` to request refresh tokens for extended sessions | | `state` | Random string generated by your application Recommended Scalekit returns this unchanged. Use it to prevent CSRF attacks and maintain request state | | `prompt` | Value to control the authentication flow Optional Use `login` to force re-authentication even when the user has a valid session. Send it only when you need to re-verify identity — including it on routine logins re-prompts users unnecessarily, a common cause of users appearing logged out Use `create` to trigger the sign-up page Use `select_account` to force the organization selector, even if the user has an active session with an organization. The selector appears only when the user belongs to multiple organizations Use `none` to check silently whether a session exists, without showing the login or sign-up page | | `organization_id` | Skip routing the user to the hosted login page and route them to the enterprise SSO connection configured for the organization Optional | | `connection_id` | Skip routing the user to the hosted login page and route them to a specific enterprise SSO connection Optional | | `login_hint` | Used for [Home Realm Discovery](/authenticate/auth-methods/enterprise-sso/#identify-and-enforce-sso-for-organization-users). Scalekit extracts the email domain from `login_hint` and routes the user to the matching organization’s SSO connection based on configured domain rules Optional | | `provider` | Skip routing user to hosted login page and direct user to a specific social connection. Supported values: `google`, `microsoft`, `github`, `gitlab`, `linkedin`, and `salesforce` Optional | ## Set up login flow [Section titled “Set up login flow”](#set-up-login-flow) 1. #### Add `state` parameter recommended [Section titled “Add state parameter ”](#add-state-parameter-) Always generate a cryptographically secure random string for the `state` parameter and store it temporarily (session, local storage, cache, etc). This can be used to validate that the state value returned in the callback matches the original value you sent. This prevents **CSRF (Cross-Site Request Forgery)** attacks where an attacker tricks users into approving unauthorized authentication requests. * Node.js Generate and store state 
     ```javascript
     1
     // Generate secure random state
     2
     const state = require('crypto').randomBytes(32).toString('hex');
     3
     // Store it temporarily (session, local storage, cache, etc)
     4
     sessionStorage.oauthState = state;
     ```
 * Python Generate and store state 
     ```python
     1
     import os
     2
     import secrets
     3


     4
     # Generate secure random state
     5
     state = secrets.token_hex(32)
     6
     # Store it temporarily (session, local storage, cache, etc)
     7
     session['oauth_state'] = state
     ```
 * Go Generate and store state 
     ```go
     1
     import (
     2
         "crypto/rand"
     3
         "encoding/hex"
     4
     )
     5


     6
     // Generate secure random state
     7
     b := make([]byte, 32)
     8
     rand.Read(b)
     9
     state := hex.EncodeToString(b)
     10
     // Store it temporarily (session, local storage, cache, etc)
     11
     // Example for Go: use a storage library
     12
     // session.Set("oauth_state", state)
     ```
 * Java Generate and store state 
     ```java
     1
     import java.security.SecureRandom;
     2
     import java.util.Base64;
     3


     4
     // Generate secure random state
     5
     SecureRandom sr = new SecureRandom();
     6
     byte[] randomBytes = new byte[32];
     7
     sr.nextBytes(randomBytes);
     8
     String state = Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
     9
     // Store it temporarily (session, local storage, cache, etc)
     10
     // Example for Java: use any storage library
     11
     // session.setAttribute("oauth_state", state);
     ```
 2. #### Redirect to the authorization URL [Section titled “Redirect to the authorization URL”](#redirect-to-the-authorization-url) Use the Scalekit SDK to generate the authorization URL. This method constructs the URL locally without making network requests. Redirect users to this URL to start authentication. * Node.js Express.js 
     ```diff
     1
     import { Scalekit } from '@scalekit-sdk/node';
     2


     3
     const scalekit = new Scalekit(/* your credentials */);
     4


     5
     // Basic authorization URL for general login
     6
     const redirectUri = 'https://yourapp.com/auth/callback';
     7
     const options = {
     8
       scopes: ['openid', 'profile', 'email', 'offline_access'],
     9
       state: sessionStorage.oauthState,
     10
     };
     11


     12
     const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);
     13


     14
     // Redirect user to Scalekit's hosted login page
     15
     res.redirect(authorizationUrl);
     ```
 * Python Flask 
     ```python
     1
     from scalekit import ScalekitClient, AuthorizationUrlOptions
     2


     3
     scalekit = ScalekitClient(/* your credentials */)
     4


     5
     # Basic authorization URL for general login
     6
     redirect_uri = 'https://yourapp.com/auth/callback'
     7
     options = AuthorizationUrlOptions()
     8
     options.scopes = ['openid', 'profile', 'email', 'offline_access']
     9
     options.state = session['oauth_state']
     10


     11
     authorization_url = scalekit.get_authorization_url(redirect_uri, options)
     12


     13
     # Redirect user to Scalekit's hosted login page
     14
     return redirect(authorization_url)
     ```
 * Go Gin 
     ```go
     1
     import "github.com/scalekit-inc/scalekit-sdk-go"
     2


     3
     scalekit := scalekit.NewScalekitClient(/* your credentials */)
     4


     5
     // Basic authorization URL for general login
     6
     redirectUri := "https://yourapp.com/auth/callback"
     7
     options := scalekit.AuthorizationUrlOptions{
     8
         Scopes: []string{"openid", "profile", "email", "offline_access"},
     9
         State: "your_generated_state", // Add this line
     10
     }
     11


     12
     authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options)
     13


     14
     // Redirect user to Scalekit's hosted login page
     15
     c.Redirect(http.StatusFound, authorizationUrl.String())
     ```
 * Java Spring 
     ```java
     1
     import com.scalekit.ScalekitClient;
     2
     import com.scalekit.internal.http.AuthorizationUrlOptions;
     3


     4
     ScalekitClient scalekit = new ScalekitClient(/* your credentials */);
     5


     6
     // Basic authorization URL for general login
     7
     String redirectUri = "https://yourapp.com/auth/callback";
     8
     AuthorizationUrlOptions options = new AuthorizationUrlOptions();
     9
     options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access"));
     10
     options.setState("your_generated_state"); // Add this line
     11


     12
     URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options);
     13


     14
     // Redirect user to Scalekit's hosted login page
     15
     return new RedirectView(authorizationUrl.toString());
     ```
 Scalekit will try to verify the user’s identity and redirect them to your application’s callback URL. If the user is a new user, Scalekit will automatically create a new user account. ## Dedicated sign-up flow [Section titled “Dedicated sign-up flow”](#dedicated-sign-up-flow) To keep sign-up separate from login, use the `prompt: 'create'` parameter to send users straight to the dedicated sign-up page. * Node.js Express.js 
  ```diff
  1
  const redirectUri = 'http://localhost:3000/api/callback';
  2
  const options = {
  3
    scopes: ['openid', 'profile', 'email', 'offline_access'],
  4
    prompt: 'create', // explicitly takes you to sign up flow
  5
  };
  6


  7
  const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);
  8


  9
  res.redirect(authorizationUrl);
  ```
 * Python Flask 
  ```diff
  1
  from scalekit import AuthorizationUrlOptions
  2


  3
  redirect_uri = 'http://localhost:3000/api/callback'
  4
  options = AuthorizationUrlOptions()
  5
  options.scopes=['openid', 'profile', 'email', 'offline_access']
  6
  options.prompt='create'  # optional: explicitly takes you to sign up flow
  7


  8
  authorization_url = scalekit.get_authorization_url(redirect_uri, options)
  9


  10
  # For web frameworks like Flask/Django:
  11
  # return redirect(authorization_url)
  ```
 * Go Gin 
  ```diff
  1
  redirectUri := "http://localhost:3000/api/callback"
  2
  options := scalekit.AuthorizationUrlOptions{
  3
      Scopes: []string{"openid", "profile", "email", "offline_access"},
  4
      +Prompt: "create", // explicitly takes you to sign up flow
  5
  }
  6


  7
  authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options)
  8
  if err != nil {
  9
      // handle error appropriately
  10
      panic(err)
  11
  }
  12


  13
  // For web frameworks like Gin:
  14
  // c.Redirect(http.StatusFound, authorizationUrl.String())
  ```
 * Java Spring 
  ```diff
  1
  import com.scalekit.internal.http.AuthorizationUrlOptions;
  2
  import java.net.URL;
  3
  import java.util.Arrays;
  4


  5
  String redirectUri = "http://localhost:3000/api/callback";
  6
  AuthorizationUrlOptions options = new AuthorizationUrlOptions();
  7
  options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access"));
  8
  +options.setPrompt("create");
  9


  10
  URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options);
  ```
 After the user authenticates either in signup or login flows: 1. Scalekit generates an authorization code 2. Makes a callback to your registered allowed callback URL 3. Your backend exchanges the code for tokens by making a server-to-server request This approach keeps sensitive operations server-side and protects your application’s credentials. Let’s take a look at how to complete the login in the next step.

---
# DOCUMENT BOUNDARY
---

# Production readiness checklist

> A focused checklist for delivering a production-ready authentication system that's secure, reliable, and compliant

Before launching your authentication system to production, you need to ensure that every aspect of your implementation is secure, tested, and ready for real users. This checklist is organized in the order teams typically implement features when going live, starting with defining your requirements and moving through core flows to advanced features. Use this checklist systematically to verify that your authentication implementation meets production standards. Each section addresses critical aspects of a production-ready authentication system, from security hardening to user experience testing. ## Define your auth surface [Section titled “Define your auth surface”](#define-your-auth-surface) Determine which authentication methods and features you need at launch. This prevents enabling features you don’t need and helps focus your testing efforts. * \[ ] Decide which login methods to enable (email/password, magic links, social logins, passkeys) * \[ ] Test all enabled authentication methods from initiation to completion * \[ ] Verify social login integrations with your configured providers (Google, Microsoft, GitHub, etc.) * \[ ] Test passkey authentication flows (if enabled) * \[ ] Verify auth method selection UI works correctly * \[ ] Test fallback scenarios when auth methods fail * \[ ] Determine if you’re supporting enterprise customers at launch (SSO, SCIM, admin portal) * \[ ] Configure proper CORS settings (restrict allowed origins to your domains) ## Core authentication flows [Section titled “Core authentication flows”](#core-authentication-flows) Verify that your core authentication flows work correctly and handle errors gracefully. These are the essential flows every application needs. * \[ ] Verify production environment configuration (environment URL, client ID, and client secret match your production environment, not dev or staging) * \[ ] Enable HTTPS for all authentication endpoints (prevents token interception) * \[ ] Test login initiation with authorization URL * \[ ] Validate redirect URLs match your dashboard configuration exactly * \[ ] Test authentication completion and code exchange * \[ ] Validate `state` parameter in callbacks to prevent CSRF attacks * \[ ] Verify session token storage with `httpOnly`, `secure`, and `sameSite` flags as required * \[ ] Configure token lifetimes appropriate for your security requirements * \[ ] Test session timeout and automatic token refresh * \[ ] Verify logout functionality clears sessions completely * \[ ] Test error handling for expired tokens, invalid codes, and network failures * \[ ] Test the complete flow end-to-end in a staging environment ## Network and firewall configuration [Section titled “Network and firewall configuration”](#network-and-firewall-configuration) If you’re enabling enterprise SSO or SCIM provisioning for your customers, verify network access early to avoid deployment blockers. * \[ ] Verify customer firewalls allow Scalekit domains * \[ ] Test authentication from customer’s network environment * \[ ] Confirm no proxy servers block Scalekit endpoints **Domains to whitelist for customer VPNs and firewalls** If your customers deploy Scalekit behind a corporate firewall or VPN, they need to whitelist these Scalekit domains: | Domain | Purpose | | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | `.scalekit.com` | Your Scalekit environment URL (admin portal and authentication; replace this with your actual Scalekit environment URL) | | `cdn.scalekit.com` | Content delivery network for static assets | | `docs.scalekit.com` | Documentation portal | | `fonts.googleapis.com` | Font resources | Replace `.scalekit.com` with your actual Scalekit environment URL from the Scalekit dashboard. ## Enterprise auth [Section titled “Enterprise auth”](#enterprise-auth) If you’re supporting enterprise customers, configure SSO, SCIM provisioning, and the admin portal. ### SSO flows [Section titled “SSO flows”](#sso-flows) * \[ ] Test SSO integrations with your target identity providers (Okta, Azure AD, Google Workspace) * \[ ] Configure SSO user attribute mapping (email, name, groups) * \[ ] Set up admin portal for enterprise customers to configure their SSO * \[ ] Test both SP-initiated and IdP-initiated SSO flows * \[ ] Verify SSO error handling for misconfigured connections * \[ ] Test SSO with different user scenarios (new users, existing users, deactivated users) * \[ ] Register all organization domains for [JIT provisioning](/authenticate/manage-users-orgs/jit-provisioning/) (enables automatic user creation) * \[ ] Configure consistent user identifiers across all SSO connections (email, userPrincipalName, etc.) * \[ ] Set appropriate default roles for JIT-provisioned users based on your security requirements * \[ ] Enable “Sync user attributes during login” to keep user profiles updated from the identity provider * \[ ] Monitor JIT activity and regularly review automatically provisioned users for security * \[ ] Plan for manual invitations for contractors and external users with non-matching domains ### SCIM provisioning [Section titled “SCIM provisioning”](#scim-provisioning) * \[ ] Configure webhook endpoints to receive SCIM events * \[ ] Verify webhook security with signature validation * \[ ] Test user provisioning flow (create users automatically) * \[ ] Test user deprovisioning flow (deactivate/delete users automatically) * \[ ] Test user updates (profile changes, role updates) * \[ ] Set up group-based role assignment and synchronization * \[ ] Test error scenarios (duplicate users, invalid data) ### Admin portal [Section titled “Admin portal”](#admin-portal) * \[ ] Configure admin portal access for enterprise customers * \[ ] Test admin portal SSO configuration flows * \[ ] Verify admin portal user management features ## Customization [Section titled “Customization”](#customization) Ensure your authentication experience matches your brand identity and custom requirements. * \[ ] Brand your login page with your logo, colors, and styling * \[ ] Customize email templates for sign-up, password reset, and invitations * \[ ] Configure custom domain for authentication pages (if applicable) * \[ ] Set up your preferred email provider in **Dashboard > Customization > Emails** * \[ ] Test email deliverability and check spam folders * \[ ] Configure custom user attributes (if needed) * \[ ] Set up auth flow interceptors (if using) * \[ ] Configure webhooks for auth events (if using) * \[ ] Verify webhook security with signature validation * \[ ] Review and rotate API credentials (store in environment variables, never commit to code) ## User and organization management [Section titled “User and organization management”](#user-and-organization-management) Configure how users and organizations are managed in your application. * \[ ] Configure user profile fields you need to collect during sign-up * \[ ] Set up organization management (workspaces, teams, tenants) * \[ ] Test organization creation flow * \[ ] Test adding users to organizations * \[ ] Test removing users from organizations * \[ ] Test user invitation flow and email templates * \[ ] Set allowed email domains for organization sign-ups (if applicable) * \[ ] Verify organization switching works for users in multiple organizations * \[ ] Test user and organization deletion flows * \[ ] Review [user management settings](/authenticate/fsa/user-management-settings) in your dashboard If you’re implementing role-based access control (RBAC), verify these authorization items: * \[ ] Define and create roles and permissions * \[ ] Configure default roles for new users * \[ ] Test role assignment to users * \[ ] Test role assignment to organization members * \[ ] Verify permission checks in application code * \[ ] Test access control for different role levels * \[ ] Validate permission enforcement at API endpoints ## MCP authentication [Section titled “MCP authentication”](#mcp-authentication) If you’re implementing MCP authentication for AI agents, verify these items. * \[ ] Test MCP server authentication flow * \[ ] Verify OAuth consent screen for MCP clients * \[ ] Test token exchange for MCP connections * \[ ] Verify custom auth handlers (if using) * \[ ] Test MCP session management * \[ ] Review [MCP troubleshooting](/authenticate/mcp/troubleshooting/) documentation ## Monitoring, logs, and incident readiness [Section titled “Monitoring, logs, and incident readiness”](#monitoring-logs-and-incident-readiness) Set up monitoring to track authentication activity and troubleshoot issues quickly. * \[ ] Set up authentication logs monitoring in **Dashboard > Auth Logs** * \[ ] Configure alerts for suspicious activity (multiple failed login attempts, unusual locations) * \[ ] Set up webhook event monitoring and logging * \[ ] Create dashboards for key metrics (sign-ups, logins, failures, session durations) * \[ ] Set up error tracking for authentication failures * \[ ] Configure log retention policies * \[ ] Test webhook delivery and retry mechanisms * \[ ] Review [auth logs](/guides/dashboard/auth-logs) documentation * \[ ] Configure [webhook best practices](/guides/webhooks-best-practices) for reliable event handling

---
# DOCUMENT BOUNDARY
---

# Bring your own credentials

> Configure your own OAuth app credentials so users see your brand on consent screens, not Scalekit's.

By default, Scalekit uses its own OAuth app credentials when your users go through the OAuth consent flow. This works for development and testing, but in production your users will see Scalekit’s name and branding on the consent screen, not yours. **Bring your own credentials** lets you replace Scalekit’s shared OAuth credentials with your own. Once configured, users see your app name, logo, and terms on every OAuth consent screen. ## What changes when you use your own credentials [Section titled “What changes when you use your own credentials”](#what-changes-when-you-use-your-own-credentials) * **Consent screens** display your application’s name and branding * **Rate limits and quotas** are tied to your OAuth app, not Scalekit’s shared pool * **Provider relationship** is direct, and your OAuth app appears in provider dashboards and audit logs * **Compliance**: useful if your organization requires a direct relationship with each OAuth provider Nothing changes in your code or the Scalekit SDK. The switch is purely a dashboard configuration on the connection. ## Configure your credentials [Section titled “Configure your credentials”](#configure-your-credentials) 1. ### Copy the redirect URI from Scalekit [Section titled “Copy the redirect URI from Scalekit”](#copy-the-redirect-uri-from-scalekit) Go to **AgentKit** > **Connections** and click **Edit** on the connection you want to update. Select **Use your own credentials**. The form expands and displays a **Redirect URI**. Copy it. 2. ### Register your OAuth app with the provider [Section titled “Register your OAuth app with the provider”](#register-your-oauth-app-with-the-provider) In the provider’s developer console, create a new OAuth app (or use an existing one). Add the Redirect URI you copied in the previous step to the list of authorized redirect URIs. Redirect URI must match exactly The URI must match character-for-character. A mismatch will cause OAuth flows to fail with a redirect\_uri\_mismatch error. The provider gives you a **Client ID** and **Client Secret** after registration. Many provider consoles create the app in an internal or development mode by default. That works for your own testing but is not sufficient for customer consent. 3. ### Enter your credentials and save [Section titled “Enter your credentials and save”](#enter-your-credentials-and-save) Back in Scalekit Dashboard, enter the **Client ID** and **Client Secret** from your OAuth app and click **Save**. All new OAuth flows for this connection will now use your credentials. Saving credentials only wires your app into Scalekit. Before customers can connect, promote the app to allow external accounts and validate it end-to-end — see the [AgentKit launch checklist](/agentkit/advanced/launch-checklist/). ## Existing connected accounts [Section titled “Existing connected accounts”](#existing-connected-accounts) Existing connected accounts are not affected immediately Switching credentials does not re-authorize users who are already active. They continue using the previous credentials until they re-authorize. If you need all users to see your branding immediately, generate new authorization links and prompt them to re-authorize.

---
# DOCUMENT BOUNDARY
---

# Set up a custom domain

> Replace the default Scalekit endpoint with your own branded domain using CNAME configuration.

Custom domains enable you to offer a fully branded experience. By default, Scalekit assigns a unique endpoint URL, but you can replace it via CNAME configuration. The custom domain also applies to the authorization server URL shown on the OAuth consent screen during MCP authentication; users will see your branded domain instead of the auto-generated `yourapp-xxxx.scalekit.com`. | Before | After | | ------------------------------ | -------------------------- | | `https://yourapp.scalekit.com` | `https://auth.yourapp.com` | * **Environment:** CNAME configuration is available only for production environments * **SSL:** After successful CNAME configuration, an SSL certificate for your custom domain is automatically provisioned ## Set up your custom domain [Section titled “Set up your custom domain”](#set-up-your-custom-domain) ![Scalekit Settings Custom Domain tab showing the subdomain URL field and a CNAME record in the DNS configuration table](/.netlify/images?url=_astro%2F1.BktW9U-H.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) To set up your custom domain: 1. Go to your domain’s DNS registrar 2. Add a new record to your DNS settings and select **CNAME** as the record type 3. Switch to production environment in the Scalekit dashboard 4. Copy the **Name** (your desired subdomain) from the Scalekit dashboard > Settings > Custom domains and paste it into the **Name/Label/Host** field in your DNS registrar 5. Copy the **Value** from the Scalekit dashboard > Settings > Custom domains and paste it into the **Destination/Target/Value** field in your DNS registrar 6. Save the record in your DNS registrar 7. In the Scalekit dashboard, click **Verify** CNAME record changes can take up to 72 hours to propagate, although they typically happen much sooner. ## Troubleshoot CNAME verification [Section titled “Troubleshoot CNAME verification”](#troubleshoot-cname-verification) If there are any issues during the CNAME verification step: * Double-check your DNS configuration to ensure all values are correctly entered * Once the CNAME changes take effect, Scalekit will automatically provision an SSL certificate for your custom domain. This process can take up to 24 hours You can click on the **Check** button in the Scalekit dashboard to verify SSL certification status. If SSL provisioning takes longer than 24 hours, please contact us at [](mailto:support@scalekit.com) ## DNS registrar guides [Section titled “DNS registrar guides”](#dns-registrar-guides) For detailed instructions on adding a CNAME record in specific registrars: * [GoDaddy: Add a CNAME record](https://www.godaddy.com/en-in/help/add-a-cname-record-19236) * [Namecheap: How to create a CNAME record](https://www.namecheap.com/support/knowledgebase/article.aspx/9646/2237/how-to-create-a-cname-record-for-your-domain)

---
# DOCUMENT BOUNDARY
---

# AgentKit launch checklist

> Verify your AgentKit integration is production-ready before going live.

Use this checklist before moving your AgentKit integration to production. ## Environment and credentials [Section titled “Environment and credentials”](#environment-and-credentials) * \[ ] Switch to the production environment in the Scalekit dashboard * \[ ] Set `SCALEKIT_ENV_URL`, `SCALEKIT_CLIENT_ID`, and `SCALEKIT_CLIENT_SECRET` to production values, not dev or staging ## Connections [Section titled “Connections”](#connections) * \[ ] All connectors your agent uses are configured in the production environment * \[ ] Each connection shows as active in the dashboard * \[ ] Connection names used in code match the names in the dashboard exactly ## Connector OAuth apps (if you registered your own app) [Section titled “Connector OAuth apps (if you registered your own app)”](#connector-oauth-apps-if-you-registered-your-own-app) Complete this section for any connector where you registered the OAuth app yourself in the provider’s console. Providers create new OAuth apps in a development or test mode that authorizes only the account that created the app. The connection works while you build and test with your own account, then fails for customer tenants in production — for example, Airtable returns “OAuth app can’t be used outside development,” and ZoomInfo requires a partner application rather than a custom (internal) app for cross-account access. * \[ ] Provider OAuth app is promoted out of development or test mode (published, production, or partner — depending on the provider) so accounts outside your own can authorize * \[ ] Provider app profile is complete where the provider requires it before publishing (logo, terms of service, privacy policy — for example, Airtable Builder Hub) * \[ ] After promoting the app, `client_id`, `client_secret`, redirect URI, and scopes still match between the provider and Scalekit (promotion can rotate the `client_id`) * \[ ] Authorization tested with an account outside the workspace that created the app, not only your own test account ## Authorization and connected accounts [Section titled “Authorization and connected accounts”](#authorization-and-connected-accounts) * \[ ] End-to-end authorization flow tested with a real user account in production * \[ ] Connected accounts created and verified for at least one test user * \[ ] Magic link generation and redirect tested (OAuth connectors) * \[ ] Re-authorization flow tested: verify behavior when a token expires or is revoked ## Security [Section titled “Security”](#security) * \[ ] MCP URLs are generated and consumed server-side only; never passed to or generated in client-side code * \[ ] `identifier` values passed to Tool Proxy are tied to authenticated users, not shared, static, or guessable * \[ ] Session tokens are minted fresh before each agent run and not reused across sessions ## Custom connector (if applicable) [Section titled “Custom connector (if applicable)”](#custom-connector-if-applicable) * \[ ] Connector definition promoted from Dev to Production (see [Create your own connector](/agentkit/bring-your-own-connector/create-connector)) * \[ ] Auth pattern validated with a real connected account in production * \[ ] Tool Proxy calls return expected responses against the production upstream API ## Go live [Section titled “Go live”](#go-live) * \[ ] Custom domain configured and SSL verified (see [Custom domain](/agentkit/advanced/custom-domain))

---
# DOCUMENT BOUNDARY
---

# Migrate from Composio to Scalekit

> Map Composio concepts to Scalekit AgentKit equivalents and update your agent code step by step.

This guide maps Composio concepts to their Scalekit AgentKit equivalents and walks through each migration step: SDK setup, authentication, tool execution, and MCP. Use it as a reference while porting your agent code. ## Concept mapping [Section titled “Concept mapping”](#concept-mapping) | Composio | Scalekit | Notes | | ------------------------------------ | ------------------------------------------ | --------------------------------------------------------------- | | Toolkit (e.g. `GITHUB`) | **Connector** (e.g. `github`) | Scalekit uses lowercase slugs | | Tool (e.g. `GITHUB_CREATE_ISSUE`) | **Tool** (e.g. `github_create_issue`) | Same concept, lowercase naming | | Auth config | **Connection** | OAuth app credentials, scopes, redirect URIs | | Connected account | **Connected account** | Per-user credential record | | `user_id` / entity ID | **`identifier`** | Your app’s unique user ID, passed per API call | | Connect Link | **Authorization link** | OAuth redirect URL for user consent | | Session (`composio.create()`) | No equivalent | Scalekit is stateless — pass `identifier` per call | | Provider package (`composio_openai`) | No equivalent | Scalekit uses a single SDK for all frameworks | | `session.tools()` | `listScopedTools()` | Get tools a user is authorized to call | | `session.tools.execute()` | `executeTool()` | Execute a tool on behalf of a user | | `session.mcp.url` | **Virtual MCP Server URL + session token** | Static server URL with a short-lived bearer token per agent run | | Custom tool (in-memory) | **Custom tool** (API Proxy) | Defined in your app code using `actions.request()` | | `executeToolRequest` (proxy) | `actions.request()` | Proxied REST API call | | Trigger | No equivalent | Scalekit does not support event-driven triggers | | `COMPOSIO_SEARCH_TOOLS` | No equivalent | Use `listScopedTools` with connection name filters | | `COMPOSIO_REMOTE_WORKBENCH` | No equivalent | No remote sandbox execution | ## 1. Set up Scalekit [Section titled “1. Set up Scalekit”](#1-set-up-scalekit) 1. **Create a Scalekit account** Sign up at [app.scalekit.com](https://app.scalekit.com) and copy your API credentials from **Dashboard > Developers > Settings > API Credentials**. 2. **Set environment variables** 
   ```bash
   1
   SCALEKIT_CLIENT_ID=your_client_id
   2
   SCALEKIT_CLIENT_SECRET=your_client_secret
   3
   SCALEKIT_ENV_URL=https://your-env.scalekit.com
   ```
 3. **Install the SDK** * Python 
     ```bash
     1
     pip install scalekit-sdk-python
     ```
 * Node.js 
     ```bash
     1
     npm install @scalekit-sdk/node
     ```
 4. **Initialize the client** Scalekit uses a single client instance. There is no session object — you pass `identifier` on each API call. * Python 
     ```python
     1
     import os
     2
     import scalekit.client
     3


     4
     scalekit_client = scalekit.client.ScalekitClient(
     5
         client_id=os.getenv("SCALEKIT_CLIENT_ID"),
     6
         client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
     7
         env_url=os.getenv("SCALEKIT_ENV_URL"),
     8
     )
     9
     actions = scalekit_client.actions
     ```
 * Node.js 
     ```typescript
     1
     import { ScalekitClient } from '@scalekit-sdk/node';
     2


     3
     const scalekit = new ScalekitClient(
     4
       process.env.SCALEKIT_ENV_URL!,
     5
       process.env.SCALEKIT_CLIENT_ID!,
     6
       process.env.SCALEKIT_CLIENT_SECRET!
     7
     );
     ```
 ## 2. Configure connections [Section titled “2. Configure connections”](#2-configure-connections) In Composio, auth configs are created programmatically or via the dashboard. In Scalekit, you configure **connections** in the dashboard. For each Composio toolkit your agent uses (Gmail, Slack, GitHub, etc.), create a corresponding connection in **Dashboard > AgentKit > Connections > Add connection**. See [Configure a connection](/agentkit/connections/) for the full walkthrough. | Composio auth type | Scalekit equivalent | | ---------------------------- | ------------------------------------------------------------------ | | OAuth 2.0 (Composio managed) | OAuth 2.0 (use Scalekit credentials to start, then bring your own) | | OAuth 2.0 (custom) | OAuth 2.0 (bring your own credentials) | | API key | API key (user provides during connected account creation) | | Bearer token | Bearer token | | Basic auth | Basic auth | ## 3. Migrate authentication [Section titled “3. Migrate authentication”](#3-migrate-authentication) Both platforms create per-user records (connected accounts) and generate OAuth links. The SDK methods differ. #### Create a connected account and authorize [Section titled “Create a connected account and authorize”](#create-a-connected-account-and-authorize) * Python **Before (Composio):** 
  ```python
  1
  # Composio handles auth in-chat or via connect link
  2
  session = composio.create(user_id="user_123")
  3
  # Auth is triggered automatically when a tool requires it
  ```
 **After (Scalekit):** 
  ```python
  1
  # Create or retrieve the connected account
  2
  response = actions.get_or_create_connected_account(
  3
      connection_name="gmail",
  4
      identifier="user_123",
  5
  )
  6
  connected_account = response.connected_account
  7


  8
  # Generate an authorization link if the account is not yet active
  9
  if connected_account.status != "ACTIVE":
  10
      link_response = actions.get_authorization_link(
  11
          connection_name="gmail",
  12
          identifier="user_123",
  13
      )
  14
      auth_url = link_response.link
  15
      # Redirect or send auth_url to the user
  ```
 * Node.js **Before (Composio):** 
  ```typescript
  1
  // Composio handles auth in-chat or via connect link
  2
  const session = await composio.create("user_123");
  3
  // Auth is triggered automatically when a tool requires it
  ```
 **After (Scalekit):** 
  ```typescript
  1
  // Create or retrieve the connected account
  2
  const response = await scalekit.actions.getOrCreateConnectedAccount({
  3
    connectionName: 'gmail',
  4
    identifier: 'user_123',
  5
  });
  6


  7
  const connectedAccount = response.connectedAccount;
  8


  9
  // Generate an authorization link if the account is not yet active
  10
  if (connectedAccount?.status !== 'ACTIVE') {
  11
    const linkResponse = await scalekit.actions.getAuthorizationLink({
  12
      connectionName: 'gmail',
  13
      identifier: 'user_123',
  14
    });
  15
    const authUrl = linkResponse.link;
  16
    // Redirect or send authUrl to the user
  17
  }
  ```
 **Key difference:** Composio can trigger auth in-chat automatically. With Scalekit, your app explicitly creates the connected account and sends the authorization link to the user. Once the user completes the OAuth flow, the connected account becomes `ACTIVE` and your agent can execute tools. #### Check connected account status [Section titled “Check connected account status”](#check-connected-account-status) Composio tracks two statuses (`ACTIVE` and `INACTIVE`). Scalekit uses more granular states: | Scalekit status | Meaning | | --------------- | -------------------------------------------------------------- | | `PENDING` | User hasn’t completed authentication | | `ACTIVE` | Credentials valid, ready for tool calls | | `EXPIRED` | Credentials expired or invalidated, re-authentication required | | `REVOKED` | User revoked access or credentials were invalidated | | `ERROR` | Authentication or configuration error | Check status before executing tools. If the account is not `ACTIVE`, generate a new authorization link. ## 4. Migrate tool calls [Section titled “4. Migrate tool calls”](#4-migrate-tool-calls) #### List available tools [Section titled “List available tools”](#list-available-tools) * Python **Before (Composio):** 
  ```python
  1
  session = composio.create(user_id="user_123")
  2
  tools = session.tools()  # all tools the user is authorized for
  ```
 **After (Scalekit):** 
  ```python
  1
  tools_response = scalekit_client.actions.tools.list_scoped_tools(
  2
      identifier="user_123",
  3
      filter={"connection_names": ["gmail"]},  # optional; omit for all connectors
  4
      page_size=100,
  5
  )
  ```
 * Node.js **Before (Composio):** 
  ```typescript
  1
  const session = await composio.create("user_123");
  2
  const tools = await session.tools();  // all tools the user is authorized for
  ```
 **After (Scalekit):** 
  ```typescript
  1
  const { tools } = await scalekit.tools.listScopedTools('user_123', {
  2
    filter: { connectionNames: ['gmail'] },  // optional; omit for all connectors
  3
    pageSize: 100,
  4
  });
  ```
 #### Execute a tool [Section titled “Execute a tool”](#execute-a-tool) * Python **Before (Composio):** 
  ```python
  1
  session = composio.create(user_id="user_123")
  2
  tools = session.tools()
  3
  # Framework handles execution via the agent loop, or:
  4
  # composio.tools.execute(tool_name="GMAIL_FETCH_MAILS", params={...})
  ```
 **After (Scalekit):** 
  ```python
  1
  result = actions.execute_tool(
  2
      tool_name="gmail_fetch_mails",
  3
      identifier="user_123",
  4
      connection_name="gmail",
  5
      tool_input={"query": "is:unread", "max_results": 5},
  6
  )
  7
  print(result.data)
  ```
 * Node.js **Before (Composio):** 
  ```typescript
  1
  const session = await composio.create("user_123");
  2
  const tools = await session.tools();
  3
  // Framework handles execution via the agent loop
  ```
 **After (Scalekit):** 
  ```typescript
  1
  const result = await scalekit.actions.executeTool({
  2
    toolName: 'gmail_fetch_mails',
  3
    identifier: 'user_123',
  4
    connectionName: 'gmail',
  5
    toolInput: { query: 'is:unread', max_results: 5 },
  6
  });
  7
  console.log(result.data);
  ```
 **Key differences:** * Composio tool names are uppercase (`GMAIL_FETCH_MAILS`); Scalekit uses lowercase (`gmail_fetch_mails`) * Composio’s session model means you don’t pass `user_id` on each call. With Scalekit, pass `identifier` and `connection_name` on every `executeTool` call * Both return structured, LLM-ready output ### Map tool names [Section titled “Map tool names”](#map-tool-names) Composio and Scalekit may name tools differently for the same connector. Browse the connector’s tool list in the [Scalekit connector catalog](/agentkit/connectors/) to find the exact tool names. Common patterns: | Composio tool name | Scalekit tool name | | --------------------- | --------------------- | | `GMAIL_FETCH_MAILS` | `gmail_fetch_mails` | | `SLACK_SEND_MESSAGE` | `slack_send_message` | | `GITHUB_CREATE_ISSUE` | `github_create_issue` | | `NOTION_CREATE_PAGE` | `notion_create_page` | Tool input schemas may also differ. Check each tool’s parameters in the connector catalog and update your agent’s tool input accordingly. ## 5. Migrate MCP [Section titled “5. Migrate MCP”](#5-migrate-mcp) Both platforms support MCP (Model Context Protocol) for framework-agnostic tool discovery and execution. **Before (Composio):** 
```json
1
{
2
  "mcpServers": {
3
    "composio": {
4
      "url": "https://backend.composio.dev/v3/mcp/{SERVER_ID}?user_id={USER_ID}",
5
      "headers": {
6
        "x-api-key": ""
7
      }
8
    }
9
  }
10
}
```
 **After (Scalekit):** Scalekit MCP uses Virtual MCP Servers: 1. **Create an MCP config** — define which connections and tools the server exposes (one-time). This gives you a static `mcp_server_url`. 2. **Mint a session token** — before each agent run, call `create_session_token` for the user. Pass it as a bearer auth header. See [Virtual MCP Servers](/agentkit/mcp/overview/) for the full setup. 
```json
1
{
2
  "mcpServers": {
3
    "scalekit": {
4
      "url": "",
5
      "headers": {
6
        "Authorization": "Bearer "
7
      }
8
    }
9
  }
10
}
```
 **Key difference:** Composio embeds the user ID in the URL. Scalekit uses a static server URL shared across all users, with a short-lived session token per agent run for authentication. ## 6. Migrate custom tools [Section titled “6. Migrate custom tools”](#6-migrate-custom-tools) In Composio, custom tools are defined in code with decorators and stored in memory — they’re lost on restart. In Scalekit, custom tools use **API Proxy mode** (`actions.request`). The proxy is available out of the box for every connector with no extra configuration. You define the tool contract in your application code and call the provider’s REST endpoint through Scalekit, which injects the user’s credentials automatically. | Composio approach | Scalekit approach | | ------------------------------------------------ | -------------------------------------------------------------- | | `@composio.tools.custom_tool` decorator | Define the tool in your app code | | In-memory, lost on restart | Lives in your codebase | | `executeToolRequest` for authenticated API calls | `actions.request()` — works out of the box for every connector | * Python 
  ```python
  1
  response = actions.request(
  2
      connection_name="gmail",
  3
      identifier="user_123",
  4
      method="GET",
  5
      path="/gmail/v1/users/me/messages",
  6
  )
  ```
 * Node.js 
  ```typescript
  1
  const response = await scalekit.actions.request({
  2
    connectionName: 'gmail',
  3
    identifier: 'user_123',
  4
    method: 'GET',
  5
    path: '/gmail/v1/users/me/messages',
  6
  });
  ```
 ## 7. Add custom connectors [Section titled “7. Add custom connectors”](#7-add-custom-connectors) If your agent connects to an API or MCP server that isn’t in Scalekit’s built-in catalog, you can add your own connector. Custom connectors support OAuth 2.0, API keys, bearer tokens, and other auth types. Once created, they work exactly like built-in connectors — same connected account flow, same `actions.request()` proxy, same MCP tool calling. This goes beyond what Composio offers with in-memory custom tools: Scalekit custom connectors are persistent, support any SaaS API, partner system, or internal service, and keep all credential handling centralized. See [Add your own connector](/agentkit/bring-your-own-connector/overview/) for the full walkthrough. ## Checklist [Section titled “Checklist”](#checklist) * \[ ] Scalekit account created, API credentials saved as environment variables * \[ ] Scalekit SDK installed * \[ ] Connections created in the Scalekit Dashboard for each connector * \[ ] Connected account creation and authorization link flow ported * \[ ] Tool names updated from uppercase to lowercase * \[ ] `executeTool` calls updated with `identifier` and `connection_name` * \[ ] Tool input schemas verified against the Scalekit connector catalog * \[ ] MCP config created and session token flow implemented (if using MCP) * \[ ] Custom tools ported to `actions.request()` (if applicable) * \[ ] Agent tested end-to-end with a test user * \[ ] Users re-authorized through Scalekit’s OAuth flow

---
# DOCUMENT BOUNDARY
---

# Proxy API Calls

> Use Scalekit managed authentication and make direct HTTP calls to third party applications

Even though Scalekit Agent Auth offers pre-built connector tools out of the box for the supported applications, if you would like to make direct API calls to the third party applications for any custom behaviour, you can leverage proxy\_api tool to directly invoke the third party application. Based on the connected account or user identifier details, Scalekit will automatically inject the user authorization tokens so that API calls to the third application will be successful. Proxy must be enabled per environment Proxy access for built-in providers (Gmail, Notion, Slack, and others) is **not enabled by default** on new environments. If you receive the error `proxy not enabled for provider`, contact  to enable the proxy for your environment. 
```python
1
# Fetch recent emails
2
emails = actions.tools.execute(
3
    connected_account_id=connected_account.id,
4
    tool='gmail_proxy_api',
5
    parameters={
6
        'path': '/gmail/v1/users/me/messages',
7
        'method': 'GET',
8
        'headers': [{'Content-Type': 'application/json'}],
9
        'params': [{'max_results': '5'}],
10
        'body': '' #actual JSON payload
11
    }
12
)
13


14
print(f'Recent emails: {emails.result}')
```
 As part of the above execution, Scalekit will automatically inject Bearer token in the request header before making the API call to GMAIL. ## Common scenarios [Section titled “Common scenarios”](#common-scenarios)

---
# DOCUMENT BOUNDARY
---

# Authentication Methods Comparison

> Compare different authentication methods supported by AgentKit including OAuth 2.0, API Keys, Bearer Tokens, and Custom JWT to choose the right approach.

AgentKit supports multiple authentication methods to connect with third-party providers. This guide helps you understand the differences and choose the right authentication method for your use case. ## Authentication methods overview [Section titled “Authentication methods overview”](#authentication-methods-overview) OAuth 2.0 **Most secure and widely supported** User-delegated authentication with automatic token refresh and granular permissions. **Best for:** Google, Microsoft, Slack, GitHub API Keys **Simple static credentials** Provider-issued keys for straightforward server-to-server authentication. **Best for:** Jira, Asana, Linear, Airtable Bearer Tokens **User-generated tokens** Personal access tokens with scoped permissions for individual use. **Best for:** GitHub PATs, GitLab tokens Custom JWT **Advanced signed tokens** Cryptographically signed tokens for service accounts and custom protocols. **Best for:** Custom integrations, service accounts ## Comparison matrix [Section titled “Comparison matrix”](#comparison-matrix) | Feature | OAuth 2.0 | API Keys | Bearer Tokens | Custom JWT | | ------------------------ | ---------- | -------- | ------------- | ------------ | | **Security Level** | High | Medium | Medium | High | | **User Interaction** | Required | Optional | Required | Not required | | **Token Refresh** | Automatic | N/A | Manual | Varies | | **Setup Complexity** | Moderate | Easy | Easy | Complex | | **Granular Permissions** | Yes | Limited | Yes | Limited | | **Provider Support** | Widespread | Common | Common | Limited | ## When to use each method [Section titled “When to use each method”](#when-to-use-each-method) ### OAuth 2.0 [Section titled “OAuth 2.0”](#oauth-20) **Use when:** * Provider supports OAuth * Acting on behalf of users * Need automatic token refresh * Require granular permissions * Building user-facing applications **Example:** User connects Gmail to send emails through your app ### API Keys [Section titled “API Keys”](#api-keys) **Use when:** * Provider only supports API keys * Building internal tools * Server-to-server communication * Simplicity is priority **Example:** Automated Jira ticket creation for support system ### Bearer Tokens [Section titled “Bearer Tokens”](#bearer-tokens) **Use when:** * Personal access is sufficient * Building developer tools * OAuth unavailable * User prefers manual control **Example:** Personal GitHub repository automation ### Custom JWT [Section titled “Custom JWT”](#custom-jwt) **Use when:** * Provider requires JWT * Service account access needed * Custom authentication protocol * Advanced security requirements **Example:** Enterprise service account integrations ## Next steps [Section titled “Next steps”](#next-steps) * [Connectors](/agentkit/connectors) - Available third-party providers * [Connections](/agentkit/connections) - Configure provider connections * [Authorization Methods](/agentkit/tools/authorize) - Detailed authentication implementation

---
# DOCUMENT BOUNDARY
---

# Testing Authentication Flows

> Learn how to test AgentKit authentication flows in development, staging, and production environments with comprehensive testing strategies.

Thorough testing of authentication flows ensures your AgentKit integration works reliably before production deployment. This guide covers testing strategies, tools, and best practices. ## Testing environments [Section titled “Testing environments”](#testing-environments) ### Development environment [Section titled “Development environment”](#development-environment) **Purpose:** Rapid iteration and debugging **Characteristics:** * Local development server * Test accounts and credentials * Verbose logging enabled * Quick feedback loops **Setup:** development.env 
```python
1
SCALEKIT_ENV_URL=https://your-env.scalekit.dev
2
SCALEKIT_CLIENT_ID=dev_client_id
3
SCALEKIT_CLIENT_SECRET=dev_client_secret
4
DEBUG=true
5
LOG_LEVEL=debug
```
 ### Staging environment [Section titled “Staging environment”](#staging-environment) **Purpose:** Pre-production validation **Characteristics:** * Production-like configuration * Realistic data volumes * Integration with staging third-party accounts * Performance testing **Setup:** staging.env 
```python
1
SCALEKIT_ENV_URL=https://your-env.scalekit.cloud
2
SCALEKIT_CLIENT_ID=staging_client_id
3
SCALEKIT_CLIENT_SECRET=staging_client_secret
4
DEBUG=false
5
LOG_LEVEL=info
```
 ### Production environment [Section titled “Production environment”](#production-environment) **Purpose:** Live user traffic **Characteristics:** * Real user data * Verified OAuth applications * Monitoring and alerts * Minimal logging **Setup:** production.env 
```python
1
SCALEKIT_ENV_URL=https://your-env.scalekit.cloud
2
SCALEKIT_CLIENT_ID=prod_client_id
3
SCALEKIT_CLIENT_SECRET=prod_client_secret
4
DEBUG=false
5
LOG_LEVEL=warn
```
 ## Test account setup [Section titled “Test account setup”](#test-account-setup) ### Creating test providers [Section titled “Creating test providers”](#creating-test-providers) Set up test accounts for each provider: **Google Workspace:** 1. Create test Google account 2. Enable 2FA if testing MFA scenarios 3. Use for Gmail, Calendar, Drive testing **Slack:** 1. Create free Slack workspace 2. Install your Slack app 3. Use for messaging and notification testing **Microsoft 365:** 1. Get Microsoft 365 developer account (free) 2. Create test users 3. Use for Outlook, Teams, OneDrive testing **Jira/Atlassian:** 1. Create free Atlassian Cloud account 2. Set up test projects 3. Generate API tokens for testing ### Test user patterns [Section titled “Test user patterns”](#test-user-patterns) Create different test users for scenarios: 
```python
1
# Test user configurations
2
TEST_USERS = {
3
    "basic_user": {
4
        "identifier": "test_user_001",
5
        "providers": ["gmail"],
6
        "scenario": "Single provider, basic authentication"
7
    },
8
    "power_user": {
9
        "identifier": "test_user_002",
10
        "providers": ["gmail", "slack", "jira", "calendar"],
11
        "scenario": "Multiple providers, full feature access"
12
    },
13
    "expired_user": {
14
        "identifier": "test_user_003",
15
        "providers": ["gmail"],
16
        "scenario": "Expired tokens, test refresh logic",
17
        "setup": "Manually expire tokens"
18
    },
19
    "revoked_user": {
20
        "identifier": "test_user_004",
21
        "providers": ["slack"],
22
        "scenario": "User revoked access, test re-auth flow"
23
    }
24
}
```
 ## Unit testing authentication [Section titled “Unit testing authentication”](#unit-testing-authentication) ### Test connected account creation [Section titled “Test connected account creation”](#test-connected-account-creation) * Python 
  ```python
  1
  import unittest
  2
  from unittest.mock import Mock, patch
  3


  4
  class TestConnectedAccountCreation(unittest.TestCase):
  5
      def setUp(self):
  6
          self.actions = Mock()
  7
          self.user_id = "test_user_123"
  8
          self.provider = "gmail"
  9


  10
      def test_create_connected_account_success(self):
  11
          """Test successful connected account creation"""
  12
          # Mock response
  13
          mock_response = Mock()
  14
          mock_response.connected_account = Mock(
  15
              id="account_123",
  16
              status="PENDING",
  17
              connection_name="gmail"
  18
          )
  19
          self.actions.get_or_create_connected_account.return_value = mock_response
  20


  21
          # Execute
  22
          response = self.actions.get_or_create_connected_account(
  23
              connection_name=self.provider,
  24
              identifier=self.user_id
  25
          )
  26


  27
          # Assert
  28
          self.assertEqual(response.connected_account.status, "PENDING")
  29
          self.assertEqual(response.connected_account.connection_name, "gmail")
  30


  31
      def test_generate_authorization_link(self):
  32
          """Test authorization link generation"""
  33
          mock_response = Mock()
  34
          mock_response.link = "https://accounts.google.com/oauth/authorize?..."
  35


  36
          self.actions.get_authorization_link.return_value = mock_response
  37


  38
          response = self.actions.get_authorization_link(
  39
              connection_name=self.provider,
  40
              identifier=self.user_id
  41
          )
  42


  43
          self.assertIn("https://", response.link)
  44
          self.actions.get_authorization_link.assert_called_once()
  45


  46
  if __name__ == '__main__':
  47
      unittest.main()
  ```
 * Node.js 
  ```javascript
  1
  const { describe, it, expect, jest, beforeEach } = require('@jest/globals');
  2


  3
  describe('Connected Account Creation', () => {
  4
    let mockActions;
  5
    const userId = 'test_user_123';
  6
    const provider = 'gmail';
  7


  8
    beforeEach(() => {
  9
      mockActions = {
  10
        getOrCreateConnectedAccount: jest.fn(),
  11
        getAuthorizationLink: jest.fn()
  12
      };
  13
    });
  14


  15
    it('should create connected account successfully', async () => {
  16
      // Mock response
  17
      const mockResponse = {
  18
        connectedAccount: {
  19
          id: 'account_123',
  20
          status: 'PENDING',
  21
          connectionName: 'gmail'
  22
        }
  23
      };
  24


  25
      mockActions.getOrCreateConnectedAccount.mockResolvedValue(mockResponse);
  26


  27
      // Execute
  28
      const response = await mockActions.getOrCreateConnectedAccount({
  29
        connectionName: provider,
  30
        identifier: userId
  31
      });
  32


  33
      // Assert
  34
      expect(response.connectedAccount.status).toBe('PENDING');
  35
      expect(response.connectedAccount.connectionName).toBe('gmail');
  36
    });
  37


  38
    it('should generate authorization link', async () => {
  39
      const mockResponse = {
  40
        link: 'https://accounts.google.com/oauth/authorize?...'
  41
      };
  42


  43
      mockActions.getAuthorizationLink.mockResolvedValue(mockResponse);
  44


  45
      const response = await mockActions.getAuthorizationLink({
  46
        connectionName: provider,
  47
        identifier: userId
  48
      });
  49


  50
      expect(response.link).toContain('https://');
  51
      expect(mockActions.getAuthorizationLink).toHaveBeenCalledTimes(1);
  52
    });
  53
  });
  ```
 * Go 
  ```go
  1
  package auth_test
  2


  3
  import (
  4
      "testing"
  5
      "github.com/stretchr/testify/assert"
  6
      "github.com/stretchr/testify/mock"
  7
  )
  8


  9
  type MockActions struct {
  10
      mock.Mock
  11
  }
  12


  13
  func (m *MockActions) GetOrCreateConnectedAccount(connectionName, identifier string) (*ConnectedAccountResponse, error) {
  14
      args := m.Called(connectionName, identifier)
  15
      return args.Get(0).(*ConnectedAccountResponse), args.Error(1)
  16
  }
  17


  18
  func TestCreateConnectedAccount(t *testing.T) {
  19
      // Arrange
  20
      mockActions := new(MockActions)
  21
      userId := "test_user_123"
  22
      provider := "gmail"
  23


  24
      expectedResponse := &ConnectedAccountResponse{
  25
          ConnectedAccount: ConnectedAccount{
  26
              ID:             "account_123",
  27
              Status:         "PENDING",
  28
              ConnectionName: "gmail",
  29
          },
  30
      }
  31


  32
      mockActions.On("GetOrCreateConnectedAccount", provider, userId).
  33
          Return(expectedResponse, nil)
  34


  35
      // Act
  36
      response, err := mockActions.GetOrCreateConnectedAccount(provider, userId)
  37


  38
      // Assert
  39
      assert.NoError(t, err)
  40
      assert.Equal(t, "PENDING", response.ConnectedAccount.Status)
  41
      assert.Equal(t, "gmail", response.ConnectedAccount.ConnectionName)
  42
      mockActions.AssertExpectations(t)
  43
  }
  ```
 * Java 
  ```java
  1
  import org.junit.jupiter.api.BeforeEach;
  2
  import org.junit.jupiter.api.Test;
  3
  import org.mockito.Mock;
  4
  import org.mockito.MockitoAnnotations;
  5
  import static org.junit.jupiter.api.Assertions.*;
  6
  import static org.mockito.Mockito.*;
  7


  8
  class ConnectedAccountCreationTest {
  9
      @Mock
  10
      private Actions mockActions;
  11


  12
      private String userId;
  13
      private String provider;
  14


  15
      @BeforeEach
  16
      void setUp() {
  17
          MockitoAnnotations.openMocks(this);
  18
          userId = "test_user_123";
  19
          provider = "gmail";
  20
      }
  21


  22
      @Test
  23
      void testCreateConnectedAccountSuccess() {
  24
          // Arrange
  25
          ConnectedAccount account = new ConnectedAccount();
  26
          account.setId("account_123");
  27
          account.setStatus("PENDING");
  28
          account.setConnectionName("gmail");
  29


  30
          ConnectedAccountResponse mockResponse = new ConnectedAccountResponse();
  31
          mockResponse.setConnectedAccount(account);
  32


  33
          when(mockActions.getOrCreateConnectedAccount(provider, userId))
  34
              .thenReturn(mockResponse);
  35


  36
          // Act
  37
          ConnectedAccountResponse response = mockActions
  38
              .getOrCreateConnectedAccount(provider, userId);
  39


  40
          // Assert
  41
          assertEquals("PENDING", response.getConnectedAccount().getStatus());
  42
          assertEquals("gmail", response.getConnectedAccount().getConnectionName());
  43
          verify(mockActions, times(1)).getOrCreateConnectedAccount(provider, userId);
  44
      }
  45
  }
  ```
 ### Test token refresh logic [Section titled “Test token refresh logic”](#test-token-refresh-logic) 
```python
1
def test_token_refresh_scenarios(self):
2
    """Test various token refresh scenarios"""
3
    test_cases = [
4
        {
5
            "name": "successful_refresh",
6
            "initial_status": "EXPIRED",
7
            "expected_status": "ACTIVE",
8
            "should_succeed": True
9
        },
10
        {
11
            "name": "refresh_token_invalid",
12
            "initial_status": "EXPIRED",
13
            "expected_status": "EXPIRED",
14
            "should_succeed": False
15
        },
16
        {
17
            "name": "already_active",
18
            "initial_status": "ACTIVE",
19
            "expected_status": "ACTIVE",
20
            "should_succeed": True
21
        }
22
    ]
23


24
    for case in test_cases:
25
        with self.subTest(case=case["name"]):
26
            # Setup mock
27
            mock_account = Mock()
28
            mock_account.status = case["expected_status"]
29


30
            if case["should_succeed"]:
31
                self.actions.refresh_connected_account.return_value = mock_account
32
            else:
33
                self.actions.refresh_connected_account.side_effect = Exception("Refresh failed")
34


35
            # Execute
36
            try:
37
                result = self.actions.refresh_connected_account(
38
                    identifier="test_user",
39
                    connection_name="gmail"
40
                )
41
                success = True
42
            except Exception:
43
                success = False
44


45
            # Assert
46
            self.assertEqual(success, case["should_succeed"])
```
 ## Integration testing [Section titled “Integration testing”](#integration-testing) ### Test complete authentication flow [Section titled “Test complete authentication flow”](#test-complete-authentication-flow) 
```python
1
import time
2


3
def test_complete_oauth_flow_integration():
4
    """
5
    Integration test for complete OAuth authentication flow.
6
    Requires manual intervention for OAuth consent.
7
    """
8
    user_id = "integration_test_user"
9
    provider = "gmail"
10


11
    # Step 1: Create connected account
12
    print("Step 1: Creating connected account...")
13
    response = actions.get_or_create_connected_account(
14
        connection_name=provider,
15
        identifier=user_id
16
    )
17


18
    account = response.connected_account
19
    assert account.status == "PENDING", f"Expected PENDING, got {account.status}"
20
    print(f"✓ Connected account created: {account.id}")
21


22
    # Step 2: Generate authorization link
23
    print("\nStep 2: Generating authorization link...")
24
    link_response = actions.get_authorization_link(
25
        connection_name=provider,
26
        identifier=user_id
27
    )
28


29
    print(f"✓ Authorization link: {link_response.link}")
30
    print("\n⚠ MANUAL STEP: Open this link in a browser and complete OAuth")
31
    print("   Press Enter after completing OAuth flow...")
32
    input()
33


34
    # Step 3: Verify account is now active
35
    print("\nStep 3: Verifying account status...")
36
    time.sleep(2)  # Brief delay for processing
37


38
    account = actions.get_connected_account(
39
        identifier=user_id,
40
        connection_name=provider
41
    )
42


43
    assert account.status == "ACTIVE", f"Expected ACTIVE, got {account.status}"
44
    print(f"✓ Account is ACTIVE")
45
    print(f"  Granted scopes: {account.scopes}")
46


47
    # Step 4: Test tool execution
48
    print("\nStep 4: Testing tool execution...")
49
    result = actions.execute_tool(
50
        identifier=user_id,
51
        tool_name="gmail_get_profile",
52
        tool_input={}
53
    )
54


55
    assert result is not None, "Tool execution failed"
56
    print(f"✓ Tool executed successfully")
57


58
    print("\n✓✓✓ Integration test completed successfully")
59


60
# Run with: pytest test_auth_integration.py -s (to see output)
```
 ### Test error scenarios [Section titled “Test error scenarios”](#test-error-scenarios) 
```python
1
def test_error_scenarios():
2
    """Test various error scenarios"""
3
    user_id = "error_test_user"
4


5
    # Test 1: Invalid provider
6
    print("Test 1: Invalid provider...")
7
    try:
8
        actions.get_or_create_connected_account(
9
            connection_name="invalid_provider",
10
            identifier=user_id
11
        )
12
        assert False, "Should have raised error"
13
    except Exception as e:
14
        print(f"✓ Caught expected error: {type(e).__name__}")
15


16
    # Test 2: Execute tool without authentication
17
    print("\nTest 2: Tool execution without auth...")
18
    try:
19
        actions.execute_tool(
20
            identifier="nonexistent_user",
21
            tool_name="gmail_send_email",
22
            tool_input={"to": "test@example.com"}
23
        )
24
        assert False, "Should have raised error"
25
    except Exception as e:
26
        print(f"✓ Caught expected error: {type(e).__name__}")
27


28
    # Test 3: Missing required scopes
29
    print("\nTest 3: Missing required scopes...")
30
    # This test requires setup with insufficient scopes
31
    print("⚠ Skipped: Requires special setup")
32


33
    print("\n✓✓✓ Error scenario tests completed")
```
 ## Automated testing [Section titled “Automated testing”](#automated-testing) ### Test authentication in CI/CD [Section titled “Test authentication in CI/CD”](#test-authentication-in-cicd) .github/workflows/test-auth.yml 
```yaml
1
name: Test Authentication Flows
2


3
on: [push, pull_request]
4


5
jobs:
6
  test:
7
    runs-on: ubuntu-latest
8


9
    steps:
10
      - uses: actions/checkout@v2
11


12
      - name: Set up Python
13
        uses: actions/setup-python@v2
14
        with:
15
          python-version: '3.9'
16


17
      - name: Install dependencies
18
        run: |
19
          pip install -r requirements.txt
20
          pip install pytest pytest-cov
21


22
      - name: Run unit tests
23
        env:
24
          SCALEKIT_CLIENT_ID: ${{ secrets.TEST_CLIENT_ID }}
25
          SCALEKIT_CLIENT_SECRET: ${{ secrets.TEST_CLIENT_SECRET }}
26
          SCALEKIT_ENV_URL: ${{ secrets.TEST_ENV_URL }}
27
        run: |
28
          pytest tests/test_auth.py -v --cov=src/auth
29


30
      - name: Run integration tests (non-OAuth)
31
        env:
32
          SCALEKIT_CLIENT_ID: ${{ secrets.TEST_CLIENT_ID }}
33
          SCALEKIT_CLIENT_SECRET: ${{ secrets.TEST_CLIENT_SECRET }}
34
          SCALEKIT_ENV_URL: ${{ secrets.TEST_ENV_URL }}
35
        run: |
36
          pytest tests/test_auth_integration.py -v -k "not oauth"
```
 ### Mock OAuth flows [Section titled “Mock OAuth flows”](#mock-oauth-flows) 
```python
1
from unittest.mock import patch, Mock
2


3
def test_oauth_flow_with_mocks():
4
    """Test OAuth flow with mocked responses (no actual OAuth)"""
5


6
    with patch('scalekit.actions.get_or_create_connected_account') as mock_create, \
7
         patch('scalekit.actions.get_authorization_link') as mock_link, \
8
         patch('scalekit.actions.get_connected_account') as mock_get:
9


10
        # Mock connected account creation
11
        mock_account = Mock()
12
        mock_account.id = "account_123"
13
        mock_account.status = "PENDING"
14


15
        mock_response = Mock()
16
        mock_response.connected_account = mock_account
17
        mock_create.return_value = mock_response
18


19
        # Mock authorization link
20
        mock_link_response = Mock()
21
        mock_link_response.link = "https://mock-oauth-url.com"
22
        mock_link.return_value = mock_link_response
23


24
        # Mock successful authentication (simulate user completing OAuth)
25
        mock_account.status = "ACTIVE"
26
        mock_account.scopes = ["gmail.readonly", "gmail.send"]
27
        mock_get.return_value = mock_account
28


29
        # Test the flow
30
        # 1. Create account
31
        response = mock_create(connection_name="gmail", identifier="user_123")
32
        assert response.connected_account.status == "PENDING"
33


34
        # 2. Get auth link
35
        link = mock_link(connection_name="gmail", identifier="user_123")
36
        assert "https://" in link.link
37


38
        # 3. Simulate user completing OAuth (status changes to ACTIVE)
39
        account = mock_get(identifier="user_123", connection_name="gmail")
40
        assert account.status == "ACTIVE"
41
        assert len(account.scopes) > 0
42


43
        print("✓ OAuth flow test with mocks completed")
```
 ## Performance testing [Section titled “Performance testing”](#performance-testing) ### Test token refresh performance [Section titled “Test token refresh performance”](#test-token-refresh-performance) 
```python
1
import time
2


3
def test_token_refresh_performance():
4
    """Measure token refresh latency"""
5
    user_id = "perf_test_user"
6
    provider = "gmail"
7


8
    # Setup: Create account with expired token
9
    # (This requires manually setting up an expired account)
10


11
    iterations = 10
12
    refresh_times = []
13


14
    for i in range(iterations):
15
        start_time = time.time()
16


17
        try:
18
            actions.refresh_connected_account(
19
                identifier=user_id,
20
                connection_name=provider
21
            )
22
            elapsed = time.time() - start_time
23
            refresh_times.append(elapsed)
24
            print(f"Iteration {i+1}: {elapsed:.3f}s")
25
        except Exception as e:
26
            print(f"Iteration {i+1} failed: {e}")
27


28
    if refresh_times:
29
        avg_time = sum(refresh_times) / len(refresh_times)
30
        min_time = min(refresh_times)
31
        max_time = max(refresh_times)
32


33
        print(f"\nToken Refresh Performance:")
34
        print(f"  Average: {avg_time:.3f}s")
35
        print(f"  Min: {min_time:.3f}s")
36
        print(f"  Max: {max_time:.3f}s")
37


38
        # Assert reasonable performance (adjust threshold as needed)
39
        assert avg_time < 2.0, f"Average refresh time too slow: {avg_time:.3f}s"
```
 ## Best practices [Section titled “Best practices”](#best-practices) ### Test checklist [Section titled “Test checklist”](#test-checklist) 1. **Unit tests** - Test individual authentication functions 2. **Integration tests** - Test complete OAuth flows 3. **Error handling** - Test all error scenarios 4. **Token refresh** - Test automatic and manual refresh 5. **Multi-provider** - Test multiple simultaneous connections 6. **Performance** - Measure and optimize latency 7. **Security** - Verify token encryption and secure storage ### Testing dos and don’ts [Section titled “Testing dos and don’ts”](#testing-dos-and-donts) ✅ **Do:** * Use separate test accounts for each provider * Test both success and failure scenarios * Mock external OAuth calls in unit tests * Test token refresh before expiration * Verify error messages are helpful * Test with realistic data volumes ❌ **Don’t:** * Use production accounts for testing * Hardcode test credentials in source code * Skip error scenario testing * Assume OAuth always succeeds * Neglect performance testing * Test only happy path scenarios ### Security testing [Section titled “Security testing”](#security-testing) 
```python
1
def test_security_scenarios():
2
    """Test security-related authentication scenarios"""
3


4
    # Test 1: Verify tokens are not exposed in logs
5
    print("Test 1: Token exposure check...")
6
    with patch('logging.Logger.debug') as mock_log:
7
        account = actions.get_connected_account(
8
            identifier="test_user",
9
            connection_name="gmail"
10
        )
11


12
        # Verify no access tokens in log calls
13
        for call in mock_log.call_args_list:
14
            log_message = str(call)
15
            assert "access_token" not in log_message.lower()
16
            assert "refresh_token" not in log_message.lower()
17


18
    print("✓ No tokens in logs")
19


20
    # Test 2: Verify HTTPS for OAuth redirects
21
    print("\nTest 2: HTTPS verification...")
22
    link_response = actions.get_authorization_link(
23
        connection_name="gmail",
24
        identifier="test_user"
25
    )
26


27
    assert link_response.link.startswith("https://")
28
    print("✓ OAuth uses HTTPS")
29


30
    # Test 3: State parameter validation
31
    print("\nTest 3: State parameter present...")
32
    assert "state=" in link_response.link
33
    print("✓ State parameter included")
34


35
    print("\n✓✓✓ Security tests completed")
```
 ## Next steps [Section titled “Next steps”](#next-steps) * [Troubleshoot connection errors](/agentkit/authentication/troubleshooting) — Debug connection and tool call issues * [Manage connected accounts](/agentkit/connected-accounts/) — Test multiple connections per user

---
# DOCUMENT BOUNDARY
---

# Troubleshoot connection errors

> Diagnose connection failures, connected account issues, and tool execution errors in AgentKit.

Use this guide when a connection fails during OAuth, a connected account shows an unexpected status, or a tool call fails. Start with the diagnostics below, then open the matching scenario. For connection setup errors (redirect URI mismatch, session expiry, token exchange failures), also see [Common scenarios on Configure connections](/agentkit/connections/#common-scenarios). ## Start with diagnostics [Section titled “Start with diagnostics”](#start-with-diagnostics) Check the connected account status first. That tells you whether the user never finished OAuth, still needs identity verification, tokens expired, or the account is disconnected. * Python 
  ```python
  1
  account = scalekit_client.actions.get_connected_account(
  2
      identifier="user_123",
  3
      connection_name="github-connect",
  4
  )
  5


  6
  print(account.status)  # ACTIVE, EXPIRED, PENDING_AUTH, PENDING_VERIFICATION, or DISCONNECTED
  7
  print(account.scopes)
  ```
 * Node.js 
  ```typescript
  1
  const account = await scalekit.actions.getConnectedAccount({
  2
    identifier: 'user_123',
  3
    connectionName: 'github-connect',
  4
  });
  5


  6
  console.log(account.status); // ACTIVE, EXPIRED, PENDING_AUTH, PENDING_VERIFICATION, or DISCONNECTED
  7
  console.log(account.scopes);
  ```
 | Status | Meaning | | ---------------------- | ---------------------------------------------------------------- | | `ACTIVE` | Credentials are valid; tool calls should work | | `EXPIRED` | Access token expired and needs refresh or re-authentication | | `PENDING_AUTH` | User has not finished OAuth, or re-authentication is in progress | | `PENDING_VERIFICATION` | OAuth succeeded; user identity verification is still required | | `DISCONNECTED` | Account was manually disconnected | If status is `ACTIVE` but a tool still fails, run a read-only tool (for example `github_user_get_authenticated`) to confirm the connection end to end. The error message usually points to scopes, credentials, or provider rate limits. To catch status changes without polling, subscribe to `connected_account.status_updated`. For automatic refresh failures, also subscribe to `connected_account.token_refresh_failed`. See [Detect when re-authentication is needed](/agentkit/connected-accounts/#detect-when-re-authentication-is-needed) for payload details and filtering. ## Connected account status [Section titled “Connected account status”](#connected-account-status) ## OAuth flow errors [Section titled “OAuth flow errors”](#oauth-flow-errors) ## Tool execution failures [Section titled “Tool execution failures”](#tool-execution-failures) ## Provider-specific errors [Section titled “Provider-specific errors”](#provider-specific-errors) ## Configuration and rate limits [Section titled “Configuration and rate limits”](#configuration-and-rate-limits) ## Get help [Section titled “Get help”](#get-help) Open **AgentKit** > **Connected Accounts** in the dashboard and review status, refresh history, and tool execution logs for the affected account. When you contact [support](mailto:support@scalekit.com), include: * Connected account ID or user `identifier` * Connection name (for example `github-connect`, `slack`) * Full error text and timestamp * Steps that reproduce the failure Related guides: * [Configure connections](/agentkit/connections/): setup, scopes, and common OAuth errors * [Manage connected accounts](/agentkit/connected-accounts/): per-user connection state and credentials

---
# DOCUMENT BOUNDARY
---

# Create your own connector

> Choose an auth type, build the connector payload, and create or manage custom connectors in Scalekit.

Create a custom connector to bring an unsupported API or MCP server into Scalekit’s secure access model. This guide walks you through building the connector payload, creating the connector, and managing it over its lifecycle - list, update, and delete - with the management API. [Check out the examples](https://github.com/scalekit-inc/python-connect-demos/tree/main/custom-connectors) ## Create a connector [Section titled “Create a connector”](#create-a-connector) Create a connector in the Scalekit Dashboard or with the management API. The dashboard provides a guided form for MCP connectors; the management API gives you scriptable control over every connector type and auth pattern. ### Create an MCP connector in the dashboard [Section titled “Create an MCP connector in the dashboard”](#create-an-mcp-connector-in-the-dashboard) Add an MCP connector through a guided form - no payload required. 1. In the Scalekit Dashboard, switch to **AgentKit**. 2. Select **Connectors**. 3. Select **Create custom connector**. 4. Complete the **Add MCP connector** form: * **Display name**: a name for the connector, such as `Example MCP`. * **Description**: a short description of what the connector connects to. * **Icon URL** (optional): an icon for the connector. Must start with `https://`. For best results, use an 800×800px SVG image, such as `https://cdn.example.com/icon.svg`. * **Server URL**: the base URL of the MCP server. Must start with `https://`, such as `https://app.example.com/mcp`. * **Metadata** (optional): key-value pairs for the connector. Values must be plain strings; nested objects are not supported. For **Auth type**, choose how users authenticate when they connect their account: * **OAuth**: users authorize access through the provider’s OAuth flow, and Scalekit handles the token exchange. * **Bearer token**: users provide a long-lived token issued by the provider. * **API key**: users provide an API key issued by the provider. * **No authentication**: the server is public and requires no credentials. Use this only when the server intentionally allows unauthenticated access and exposes no user-specific data or privileged operations, since every user shares the same anonymous access. 5. Select **Save**. The connector is ready to use when you create a connection. ### Create a connector with the management API [Section titled “Create a connector with the management API”](#create-a-connector-with-the-management-api) Build the connector payload using the reference and examples that follow, then create the connector with the management API. Below are example payloads for API and MCP connectors across all supported auth patterns. Stateless MCP servers only Scalekit connects to **stateless MCP servers** only. Stateful MCP servers that require persistent sticky connections or MCP session IDs are not supported. * API Connector * OAuth 
    ```json
    1
    {
    2
      "display_name": "My Asana",
    3
      "description": "Connect to Asana. Manage tasks, projects, teams, and workflow automation",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "OAUTH",
    7
          "display_name": "OAuth 2.0",
    8
          "description": "Authenticate with Asana using OAuth 2.0 for comprehensive project management",
    9
          "fields": [],
    10
          "oauth_config": {
    11
            "authorize_uri": "https://app.asana.com/-/oauth_authorize",
    12
            "token_uri": "https://app.asana.com/-/oauth_token",
    13
            "user_info_uri": "https://app.asana.com/api/1.0/users/me",
    14
            "available_scopes": [
    15
              {
    16
                "scope": "profile",
    17
                "display_name": "Profile",
    18
                "description": "Access user profile information",
    19
                "required": true
    20
              },
    21
              {
    22
                "scope": "email",
    23
                "display_name": "Email",
    24
                "description": "Access user email address",
    25
                "required": true
    26
              }
    27
            ]
    28
          }
    29
        }
    30
      ],
    31
      "proxy_url": "https://app.asana.com/api",
    32
      "proxy_enabled": true
    33
    }
    ```
 * Bearer 
    ```json
    1
    {
    2
      "display_name": "My Bearer Token Provider",
    3
      "description": "Connect to an API that accepts a static bearer token",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "BEARER",
    7
          "display_name": "Bearer Token",
    8
          "description": "Authenticate with a static bearer token",
    9
          "fields": [
    10
            {
    11
              "field_name": "token",
    12
              "label": "Bearer Token",
    13
              "input_type": "password",
    14
              "hint": "Your long-lived bearer token",
    15
              "required": true
    16
            }
    17
          ]
    18
        }
    19
      ],
    20
      "proxy_url": "https://api.example.com",
    21
      "proxy_enabled": true
    22
    }
    ```
 * Basic 
    ```json
    1
    {
    2
      "display_name": "My Freshdesk",
    3
      "description": "Connect to Freshdesk. Manage tickets, contacts, companies, and customer support workflows",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "BASIC",
    7
          "display_name": "Basic Auth",
    8
          "description": "Authenticate with Freshdesk using Basic Auth with username and password for comprehensive helpdesk management",
    9
          "fields": [
    10
            {
    11
              "field_name": "domain",
    12
              "label": "Freshdesk Domain",
    13
              "input_type": "text",
    14
              "hint": "Your Freshdesk domain (e.g., yourcompany.freshdesk.com)",
    15
              "required": true
    16
            },
    17
            {
    18
              "field_name": "username",
    19
              "label": "API Key",
    20
              "input_type": "text",
    21
              "hint": "Your Freshdesk API Key",
    22
              "required": true
    23
            }
    24
          ]
    25
        }
    26
      ],
    27
      "proxy_url": "https://{{domain}}/api",
    28
      "proxy_enabled": true
    29
    }
    ```
 * API Key 
    ```json
    1
    {
    2
      "display_name": "My Attention",
    3
      "description": "Connect to Attention for AI insights, conversations, teams, and workflows",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "API_KEY",
    7
          "display_name": "API Key",
    8
          "description": "Authenticate with Attention using an API Key",
    9
          "fields": [
    10
            {
    11
              "field_name": "api_key",
    12
              "label": "Integration Token",
    13
              "input_type": "password",
    14
              "hint": "Your Attention API Key",
    15
              "required": true
    16
            }
    17
          ]
    18
        }
    19
      ],
    20
      "proxy_url": "https://api.attention.tech",
    21
      "proxy_enabled": true
    22
    }
    ```
 * MCP Connector 
  ```json
  1
  {
  2
    "display_name": "My Asana",
  3
    "description": "Connect to Asana. Manage tasks, projects, teams, and workflow automation",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "OAUTH",
  7
        "display_name": "OAuth 2.0",
  8
        "description": "Authenticate with Asana using OAuth 2.0 for comprehensive project management",
  9
        "fields": [],
  10
        "oauth_config": {
  11
          "authorize_uri": "https://app.asana.com/-/oauth_authorize",
  12
          "token_uri": "https://app.asana.com/-/oauth_token",
  13
          "user_info_uri": "https://app.asana.com/api/1.0/users/me",
  14
          "available_scopes": [
  15
            {
  16
              "scope": "profile",
  17
              "display_name": "Profile",
  18
              "description": "Access user profile information",
  19
              "required": true
  20
            },
  21
            {
  22
              "scope": "email",
  23
              "display_name": "Email",
  24
              "description": "Access user email address",
  25
              "required": true
  26
            }
  27
          ]
  28
        }
  29
      }
  30
    ],
  31
    "proxy_url": "https://app.asana.com/api",
  32
    "proxy_enabled": true
  33
  }
  ```
 * OAuth 
  ```json
  1
  {
  2
    "display_name": "My Bearer Token Provider",
  3
    "description": "Connect to an API that accepts a static bearer token",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "BEARER",
  7
        "display_name": "Bearer Token",
  8
        "description": "Authenticate with a static bearer token",
  9
        "fields": [
  10
          {
  11
            "field_name": "token",
  12
            "label": "Bearer Token",
  13
            "input_type": "password",
  14
            "hint": "Your long-lived bearer token",
  15
            "required": true
  16
          }
  17
        ]
  18
      }
  19
    ],
  20
    "proxy_url": "https://api.example.com",
  21
    "proxy_enabled": true
  22
  }
  ```
 * Bearer 
  ```json
  1
  {
  2
    "display_name": "My Freshdesk",
  3
    "description": "Connect to Freshdesk. Manage tickets, contacts, companies, and customer support workflows",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "BASIC",
  7
        "display_name": "Basic Auth",
  8
        "description": "Authenticate with Freshdesk using Basic Auth with username and password for comprehensive helpdesk management",
  9
        "fields": [
  10
          {
  11
            "field_name": "domain",
  12
            "label": "Freshdesk Domain",
  13
            "input_type": "text",
  14
            "hint": "Your Freshdesk domain (e.g., yourcompany.freshdesk.com)",
  15
            "required": true
  16
          },
  17
          {
  18
            "field_name": "username",
  19
            "label": "API Key",
  20
            "input_type": "text",
  21
            "hint": "Your Freshdesk API Key",
  22
            "required": true
  23
          }
  24
        ]
  25
      }
  26
    ],
  27
    "proxy_url": "https://{{domain}}/api",
  28
    "proxy_enabled": true
  29
  }
  ```
 * Basic 
  ```json
  1
  {
  2
    "display_name": "My Attention",
  3
    "description": "Connect to Attention for AI insights, conversations, teams, and workflows",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "API_KEY",
  7
        "display_name": "API Key",
  8
        "description": "Authenticate with Attention using an API Key",
  9
        "fields": [
  10
          {
  11
            "field_name": "api_key",
  12
            "label": "Integration Token",
  13
            "input_type": "password",
  14
            "hint": "Your Attention API Key",
  15
            "required": true
  16
          }
  17
        ]
  18
      }
  19
    ],
  20
    "proxy_url": "https://api.attention.tech",
  21
    "proxy_enabled": true
  22
  }
  ```
 * API Key * OAuth 
    ```json
    1
    {
    2
      "display_name": "Github MCP",
    3
      "description": "Connect to Github MCP",
    4
      "auth_patterns": [
    5
        {
    6
          "description": "Authenticate with Github MCP using browser OAuth.",
    7
          "display_name": "OAuth 2.1/DCR",
    8
          "fields": [],
    9
          "is_mcp": true,
    10
          "oauth_config": {
    11
            "pkce_enabled": true
    12
          },
    13
          "type": "OAUTH"
    14
        }
    15
      ],
    16
      "proxy_url": "https://api.githubcopilot.com/mcp/",
    17
      "proxy_enabled": true
    18
    }
    ```
 * Bearer 
    ```json
    1
    {
    2
      "display_name": "Apify MCP",
    3
      "description": "Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows.",
    4
      "auth_patterns": [
    5
        {
    6
          "description": "Authenticate with Apify using your API Token.",
    7
          "display_name": "Apify Token",
    8
          "fields": [
    9
            {
    10
              "field_name": "token",
    11
              "hint": "Your Apify API Token",
    12
              "input_type": "password",
    13
              "label": "Apify Token",
    14
              "required": true
    15
            }
    16
          ],
    17
          "is_mcp": true,
    18
          "type": "BEARER"
    19
        }
    20
      ],
    21
      "proxy_url": "https://mcp.apify.com",
    22
      "proxy_enabled": true
    23
    }
    ```
 * Basic 
    ```json
    1
    {
    2
      "display_name": "My Internal MCP",
    3
      "description": "Connect to an internal MCP server that authenticates with a username and password",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "BASIC",
    7
          "display_name": "Basic Auth",
    8
          "description": "Authenticate with a username and password",
    9
          "is_mcp": true,
    10
          "fields": [
    11
            {
    12
              "field_name": "username",
    13
              "label": "Username",
    14
              "input_type": "text",
    15
              "hint": "Your username",
    16
              "required": true
    17
            },
    18
            {
    19
              "field_name": "password",
    20
              "label": "Password",
    21
              "input_type": "password",
    22
              "hint": "Your password",
    23
              "required": true
    24
            }
    25
          ]
    26
        }
    27
      ],
    28
      "proxy_url": "https://mcp.internal.example.com",
    29
      "proxy_enabled": true
    30
    }
    ```
 * API Key 
    ```json
    1
    {
    2
      "display_name": "My API Key MCP",
    3
      "description": "Connect to an MCP server that authenticates with a static API key",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "API_KEY",
    7
          "display_name": "API Key",
    8
          "description": "Authenticate with a static API key",
    9
          "is_mcp": true,
    10
          "fields": [
    11
            {
    12
              "field_name": "api_key",
    13
              "label": "API Key",
    14
              "input_type": "password",
    15
              "hint": "Your API key",
    16
              "required": true
    17
            }
    18
          ]
    19
        }
    20
      ],
    21
      "proxy_url": "https://mcp.example.com",
    22
      "proxy_enabled": true
    23
    }
    ```
 * No Auth 
    ```json
    1
    {
    2
      "display_name": "Public Docs MCP",
    3
      "description": "Connect to a public MCP server that requires no credentials",
    4
      "auth_patterns": [
    5
        {
    6
          "type": "NO_AUTH",
    7
          "display_name": "No Auth",
    8
          "description": "Public server - no credentials required.",
    9
          "is_mcp": true,
    10
          "fields": []
    11
        }
    12
      ],
    13
      "proxy_url": "https://mcp.example.com",
    14
      "proxy_enabled": true
    15
    }
    ```
 * OAuth 
  ```json
  1
  {
  2
    "display_name": "Github MCP",
  3
    "description": "Connect to Github MCP",
  4
    "auth_patterns": [
  5
      {
  6
        "description": "Authenticate with Github MCP using browser OAuth.",
  7
        "display_name": "OAuth 2.1/DCR",
  8
        "fields": [],
  9
        "is_mcp": true,
  10
        "oauth_config": {
  11
          "pkce_enabled": true
  12
        },
  13
        "type": "OAUTH"
  14
      }
  15
    ],
  16
    "proxy_url": "https://api.githubcopilot.com/mcp/",
  17
    "proxy_enabled": true
  18
  }
  ```
 * Bearer 
  ```json
  1
  {
  2
    "display_name": "Apify MCP",
  3
    "description": "Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows.",
  4
    "auth_patterns": [
  5
      {
  6
        "description": "Authenticate with Apify using your API Token.",
  7
        "display_name": "Apify Token",
  8
        "fields": [
  9
          {
  10
            "field_name": "token",
  11
            "hint": "Your Apify API Token",
  12
            "input_type": "password",
  13
            "label": "Apify Token",
  14
            "required": true
  15
          }
  16
        ],
  17
        "is_mcp": true,
  18
        "type": "BEARER"
  19
      }
  20
    ],
  21
    "proxy_url": "https://mcp.apify.com",
  22
    "proxy_enabled": true
  23
  }
  ```
 * Basic 
  ```json
  1
  {
  2
    "display_name": "My Internal MCP",
  3
    "description": "Connect to an internal MCP server that authenticates with a username and password",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "BASIC",
  7
        "display_name": "Basic Auth",
  8
        "description": "Authenticate with a username and password",
  9
        "is_mcp": true,
  10
        "fields": [
  11
          {
  12
            "field_name": "username",
  13
            "label": "Username",
  14
            "input_type": "text",
  15
            "hint": "Your username",
  16
            "required": true
  17
          },
  18
          {
  19
            "field_name": "password",
  20
            "label": "Password",
  21
            "input_type": "password",
  22
            "hint": "Your password",
  23
            "required": true
  24
          }
  25
        ]
  26
      }
  27
    ],
  28
    "proxy_url": "https://mcp.internal.example.com",
  29
    "proxy_enabled": true
  30
  }
  ```
 * API Key 
  ```json
  1
  {
  2
    "display_name": "My API Key MCP",
  3
    "description": "Connect to an MCP server that authenticates with a static API key",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "API_KEY",
  7
        "display_name": "API Key",
  8
        "description": "Authenticate with a static API key",
  9
        "is_mcp": true,
  10
        "fields": [
  11
          {
  12
            "field_name": "api_key",
  13
            "label": "API Key",
  14
            "input_type": "password",
  15
            "hint": "Your API key",
  16
            "required": true
  17
          }
  18
        ]
  19
      }
  20
    ],
  21
    "proxy_url": "https://mcp.example.com",
  22
    "proxy_enabled": true
  23
  }
  ```
 * No Auth 
  ```json
  1
  {
  2
    "display_name": "Public Docs MCP",
  3
    "description": "Connect to a public MCP server that requires no credentials",
  4
    "auth_patterns": [
  5
      {
  6
        "type": "NO_AUTH",
  7
        "display_name": "No Auth",
  8
        "description": "Public server - no credentials required.",
  9
        "is_mcp": true,
  10
        "fields": []
  11
      }
  12
    ],
  13
    "proxy_url": "https://mcp.example.com",
  14
    "proxy_enabled": true
  15
  }
  ```
 **Before submitting, review the final payload carefully:** * `display_name` and `description` * The selected auth `type` * Required `fields` and `account_fields` * OAuth endpoints and scopes, if the connector uses OAuth * `proxy_url` * Whether `is_mcp` is set to `true` for MCP providers Use the payload for your auth type as the request body in the create request: * cURL Terminal 
  ```bash
  1
  # $env_access_token and $SCALEKIT_CLIENT_SECRET are secrets - keep them server-side and out of source control.
  2
  # --fail-with-body makes curl exit non-zero and print the error body on a non-2xx response.
  3
  curl --fail-with-body --location "$SCALEKIT_ENVIRONMENT_URL/api/v1/custom-providers" \
  4
    --header "Authorization: Bearer $env_access_token" \
  5
    --header "Content-Type: application/json" \
  6
    --data '{...}'
  ```
 * Python The Python SDK builds the payload with typed request objects and authenticates using your client credentials - no separate access token step is needed. It covers MCP connector auth types: OAuth (via Dynamic Client Registration), Bearer, API key, and No Auth. The example below creates an OAuth MCP connector; swap the `AuthPattern` for the auth type you need. create\_connector.py 
  ```python
  1
  import scalekit.client, os
  2
  from dotenv import load_dotenv
  3
  from scalekit.actions.types import AuthPattern, OAuthConfig, CreateCustomProviderRequest
  4
  from scalekit.common.exceptions import ScalekitException
  5
  load_dotenv()
  6


  7
  # Load credentials from the environment. Keep SCALEKIT_CLIENT_SECRET server-side -
  8
  # never commit it or expose it in client-side code.
  9
  scalekit_client = scalekit.client.ScalekitClient(
  10
      client_id=os.getenv("SCALEKIT_CLIENT_ID"),
  11
      client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
  12
      env_url=os.getenv("SCALEKIT_ENV_URL"),
  13
  )
  14


  15
  try:
  16
      response = scalekit_client.actions.providers.create_custom_provider(
  17
          CreateCustomProviderRequest(
  18
              display_name="Github MCP",
  19
              description="Connect to Github MCP",
  20
              proxy_url="https://api.githubcopilot.com/mcp/",
  21
              proxy_enabled=True,
  22
              auth_patterns=[
  23
                  AuthPattern(
  24
                      type="OAUTH",
  25
                      display_name="OAuth 2.1/DCR",
  26
                      description="Authenticate with Github MCP using browser OAuth.",
  27
                      is_mcp=True,
  28
                      oauth_config=OAuthConfig(),  # pkce_enabled=True by default
  29
                  )
  30
              ],
  31
              # Optional: icon_src="https://cdn.example.com/icon.svg",
  32
              # Optional: metadata={"team": "platform"},
  33
          )
  34
      )
  35
      print("Created connector:", response.provider.identifier)
  36
  except ScalekitException as err:
  37
      # Handle validation errors, conflicts (duplicate name), auth failures, etc.
  38
      print("Failed to create connector:", err)
  39
      raise
  ```
 A successful request returns the created connector. Next, create a connection in the Scalekit Dashboard, then continue with the standard connector flow to authorize users and call tools. ## List connectors [Section titled “List connectors”](#list-connectors) List existing connectors before you create one, to confirm whether a connector for the upstream already exists. You also need the list to find a connector’s `identifier` for update and delete requests. * cURL Terminal 
  ```bash
  1
  # $env_access_token is a secret - keep it server-side and out of source control.
  2
  curl --fail-with-body --location "$SCALEKIT_ENVIRONMENT_URL/api/v1/providers?filter.provider_type=CUSTOM&page_size=1000" \
  3
    --header "Authorization: Bearer $env_access_token"
  ```
 * Python list\_connectors.py 
  ```python
  1
  import scalekit.client, os
  2
  from dotenv import load_dotenv
  3
  from scalekit.actions.types import ListProvidersRequest
  4
  from scalekit.v1.providers.providers_pb2 import ProviderType
  5
  from scalekit.common.exceptions import ScalekitException
  6
  load_dotenv()
  7


  8
  # Keep SCALEKIT_CLIENT_SECRET server-side - never commit it or expose it client-side.
  9
  scalekit_client = scalekit.client.ScalekitClient(
  10
      client_id=os.getenv("SCALEKIT_CLIENT_ID"),
  11
      client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
  12
      env_url=os.getenv("SCALEKIT_ENV_URL"),
  13
  )
  14


  15
  try:
  16
      response = scalekit_client.actions.providers.list_providers(
  17
          ListProvidersRequest(provider_type=ProviderType.CUSTOM, page_size=1000)
  18
      )
  19
      for provider in response.providers:
  20
          print(provider.identifier, provider.display_name)
  21
  except ScalekitException as err:
  22
      print("Failed to list connectors:", err)
  23
      raise
  ```
 ## Update a connector [Section titled “Update a connector”](#update-a-connector) Use the [List connectors](#list-connectors) API to get the connector `identifier`, then send the updated payload. Include `display_name`, `proxy_url`, and `auth_patterns` on every update, and echo back any other fields you want to keep - omitted fields are not preserved, so read the current connector first and change only what you need. * cURL Terminal 
  ```bash
  1
  # $env_access_token and $SCALEKIT_CLIENT_SECRET are secrets - keep them server-side and out of source control.
  2
  curl --fail-with-body --location --request PUT "$SCALEKIT_ENVIRONMENT_URL/api/v1/custom-providers/$PROVIDER_IDENTIFIER" \
  3
    --header "Authorization: Bearer $env_access_token" \
  4
    --header "Content-Type: application/json" \
  5
    --data '{...}'
  ```
 * Python update\_connector.py 
  ```python
  1
  import scalekit.client, os
  2
  from dotenv import load_dotenv
  3
  from scalekit.actions.types import ListProvidersRequest, UpdateCustomProviderRequest
  4
  from scalekit.common.exceptions import ScalekitException
  5
  load_dotenv()
  6


  7
  # Keep SCALEKIT_CLIENT_SECRET server-side - never commit it or expose it client-side.
  8
  scalekit_client = scalekit.client.ScalekitClient(
  9
      client_id=os.getenv("SCALEKIT_CLIENT_ID"),
  10
      client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
  11
      env_url=os.getenv("SCALEKIT_ENV_URL"),
  12
  )
  13


  14
  provider_identifier = "prov_..."  # from list_providers
  15


  16
  try:
  17
      # Read the current state, then echo back every field you want to keep.
  18
      current = scalekit_client.actions.providers.list_providers(
  19
          ListProvidersRequest(identifier=provider_identifier)
  20
      ).providers[0]
  21


  22
      response = scalekit_client.actions.providers.update_custom_provider(
  23
          UpdateCustomProviderRequest(
  24
              identifier=current.identifier,
  25
              display_name=current.display_name,
  26
              proxy_url=current.proxy_url,
  27
              description="Updated description",
  28
              auth_patterns=current.auth_patterns,
  29
              metadata=dict(current.metadata),
  30
          )
  31
      )
  32
      print("Updated connector:", response.provider.identifier)
  33
  except ScalekitException as err:
  34
      print("Failed to update connector:", err)
  35
      raise
  ```
 ## Delete a connector [Section titled “Delete a connector”](#delete-a-connector) Use the [List connectors](#list-connectors) API to get the connector `identifier`. If the connector is still in use, remove the related connections or connected accounts first. * cURL Terminal 
  ```bash
  1
  # $env_access_token is a secret - keep it server-side and out of source control.
  2
  curl --fail-with-body --location --request DELETE "$SCALEKIT_ENVIRONMENT_URL/api/v1/custom-providers/$PROVIDER_IDENTIFIER" \
  3
    --header "Authorization: Bearer $env_access_token"
  ```
 * Python delete\_connector.py 
  ```python
  1
  import scalekit.client, os
  2
  from dotenv import load_dotenv
  3
  from scalekit.actions.types import DeleteCustomProviderRequest
  4
  from scalekit.common.exceptions import ScalekitException
  5
  load_dotenv()
  6


  7
  # Keep SCALEKIT_CLIENT_SECRET server-side - never commit it or expose it client-side.
  8
  scalekit_client = scalekit.client.ScalekitClient(
  9
      client_id=os.getenv("SCALEKIT_CLIENT_ID"),
  10
      client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
  11
      env_url=os.getenv("SCALEKIT_ENV_URL"),
  12
  )
  13


  14
  try:
  15
      scalekit_client.actions.providers.delete_custom_provider(
  16
          DeleteCustomProviderRequest(identifier="prov_...")
  17
      )
  18
      print("Connector deleted.")
  19
  except ScalekitException as err:
  20
      # e.g. not found, or forbidden if the connector is still in use.
  21
      print("Failed to delete connector:", err)
  22
      raise
  ```
 ## Next steps [Section titled “Next steps”](#next-steps) With the connector created and a connection in place, authorize a user and start calling the upstream: * [Making tool calls](/agentkit/bring-your-own-connector/making-tool-calls) - call the upstream API or MCP server through your connector.

---
# DOCUMENT BOUNDARY
---

# Making tool calls

> Make tool calls using a REST API connector via Tool Proxy, or discover and execute tools from a custom MCP connector.

Use this page to make tool calls after the connector, connection, and connected account are set up. The call method depends on the connector type: * **REST API connectors** — use `actions.request()` to proxy HTTP calls through Tool Proxy * **MCP connectors** — use `list_scoped_tools` to discover available tools, then `execute_tool` to call them Both types use the same connection, connected account, and user authorization model. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) Make sure: * The connector exists and is configured with the right [auth pattern](/agentkit/bring-your-own-connector/create-connector) * A [connection](/agentkit/connections) is configured for the connector * The [connected account](/agentkit/connected-accounts) exists * The user has completed [authorization](/agentkit/tools/authorize) Create a connection for your connector in the Scalekit Dashboard: ![Connections page showing a custom connector connection alongside built-in connectors](/.netlify/images?url=_astro%2Fcustom-provider-connection.CmpN35cw.png\&w=2604\&h=762\&dpl=6aaa70ad2ea7b40008ad2afd) After the user completes authorization, the connected account appears in the Connected Accounts tab: ![Connected Accounts tab showing an authenticated account for a custom connector](/.netlify/images?url=_astro%2Fcustom-provider-connected-account.CNBQ7XLh.png\&w=2610\&h=624\&dpl=6aaa70ad2ea7b40008ad2afd) ## REST API proxy calls [Section titled “REST API proxy calls”](#rest-api-proxy-calls) In the request examples below, `path` is relative to the connector `proxy_url`. `connectionName` must match the connection you created, and `identifier` must match the connected account you want to use for the request. * Node.js 
  ```typescript
  1
  import { ScalekitClient } from '@scalekit-sdk/node';
  2
  import 'dotenv/config';
  3


  4
  const connectionName = 'your-provider-connection'; // get your connection name from connection configurations
  5
  const identifier = 'user_123'; // your unique user identifier
  6


  7
  // Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
  8
  const scalekit = new ScalekitClient(
  9
    process.env.SCALEKIT_ENV_URL,
  10
    process.env.SCALEKIT_CLIENT_ID,
  11
    process.env.SCALEKIT_CLIENT_SECRET
  12
  );
  13
  const actions = scalekit.actions;
  14


  15
  // Authenticate the user
  16
  const { link } = await actions.getAuthorizationLink({
  17
    connectionName,
  18
    identifier,
  19
  });
  20
  console.log('Authorize connector:', link);
  21
  process.stdout.write('Press Enter after authorizing...');
  22
  await new Promise(r => process.stdin.once('data', r));
  23


  24
  // Make a request via Scalekit proxy
  25
  const result = await actions.request({
  26
    connectionName,
  27
    identifier,
  28
    path: '/v1/customers',
  29
    method: 'GET',
  30
  });
  31
  console.log(result);
  ```
 * Python 
  ```python
  1
  import scalekit.client, os
  2
  from dotenv import load_dotenv
  3
  load_dotenv()
  4


  5
  connection_name = "your-provider-connection"  # get your connection name from connection configurations
  6
  identifier = "user_123"  # your unique user identifier
  7


  8
  # Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
  9
  scalekit_client = scalekit.client.ScalekitClient(
  10
      client_id=os.getenv("SCALEKIT_CLIENT_ID"),
  11
      client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
  12
      env_url=os.getenv("SCALEKIT_ENV_URL"),
  13
  )
  14
  actions = scalekit_client.actions
  15


  16
  # Authenticate the user
  17
  link_response = actions.get_authorization_link(
  18
      connection_name=connection_name,
  19
      identifier=identifier
  20
  )
  21
  # present this link to your user for authorization, or click it yourself for testing
  22
  print("Authorize connector:", link_response.link)
  23
  input("Press Enter after authorizing...")
  24


  25
  # Make a request via Scalekit proxy
  26
  result = actions.request(
  27
      connection_name=connection_name,
  28
      identifier=identifier,
  29
      path="/v1/customers",
  30
      method="GET"
  31
  )
  32
  print(result)
  ```
 The request shape stays the same regardless of auth type — the connector definition controls how Scalekit authenticates the call. ## MCP tool calling [Section titled “MCP tool calling”](#mcp-tool-calling) MCP connectors expose tools from the upstream MCP server. Discover the available tools, then execute them by name. Call `execute_tool` with the connection name, identifier, and any tool-specific input. Tool output lives in `response.data` — see [Understand tool response shape](/agentkit/tools/scalekit-optimized-tools/#understand-tool-response-shape) before parsing results. * Node.js 
  ```typescript
  1
  const actions = scalekit.actions;
  2


  3
  const result = await actions.executeTool({
  4
    toolName: 'tool_name_from_discovery', // replace with a name from list_scoped_tools
  5
    connector: 'your-mcp-connection',
  6
    identifier: 'user_123',
  7
    toolInput: { key: 'value' }, // replace with the tool's required input
  8
  });
  9
  console.log(result.data);
  ```
 * Python 
  ```python
  1
  actions = scalekit_client.actions
  2


  3
  result = actions.execute_tool(
  4
      tool_name="tool_name_from_discovery",  # replace with a name from list_scoped_tools
  5
      connection_name="your-mcp-connection",
  6
      identifier="user_123",
  7
      tool_input={"key": "value"},  # replace with the tool's required input
  8
  )
  9
  print(result.data)
  ```

---
# DOCUMENT BOUNDARY
---

# AgentKit code samples

> Code samples of AI agents using Scalekit along with LangChain, Google ADK, and direct integrations

### [Connect LangChain agents to Gmail](https://github.com/scalekit-inc/sample-langchain-agent) [Securely connect a LangChain agent to Gmail using Scalekit for authentication. Python example for tool authorization.](https://github.com/scalekit-inc/sample-langchain-agent) ### [Connect Google GenAI agents to Gmail](https://github.com/scalekit-inc/google-adk-agent-example) [Build a Google ADK agent that securely accesses Gmail tools. Python example demonstrating Scalekit auth integration.](https://github.com/scalekit-inc/google-adk-agent-example) ### [Connect agents to Slack tools](https://github.com/scalekit-inc/python-connect-demos/tree/main/direct) [Authorize Python agents to use Slack tools with Scalekit. Direct integration example for secure tool access.](https://github.com/scalekit-inc/python-connect-demos/tree/main/direct) ### [Browse all agent auth examples](https://github.com/scalekit-developers/agent-auth-examples) [A curated collection of working examples showing how to build agents that authenticate and access tools using Scalekit.](https://github.com/scalekit-developers/agent-auth-examples)

---
# DOCUMENT BOUNDARY
---

# Manage connected accounts

> Check status, list, delete, and update credentials for connected accounts across all connector auth types.

A **connected account** is the per-user record that holds a user’s credentials and tracks their authorization state for a specific connection. Scalekit creates one automatically when a user completes authentication. ## Account states [Section titled “Account states”](#account-states) | State | Meaning | | ---------------------- | --------------------------------------------------------------------------- | | `ACTIVE` | Credentials valid, ready for tool calls | | `EXPIRED` | Access token expired and needs refresh or re-authentication | | `PENDING_AUTH` | User hasn’t completed authentication, or re-authentication is in progress | | `PENDING_VERIFICATION` | OAuth complete; user identity verification still required before activation | | `DISCONNECTED` | Account was manually disconnected | See [Troubleshoot connection errors](/agentkit/authentication/troubleshooting/#connected-account-status) for what to do in each state. ## Check account status [Section titled “Check account status”](#check-account-status) Use `get_or_create_connected_account` as the safe default when a user may be connecting for the first time. Use `get_connected_account` only when you know the account already exists and you need to inspect or return its stored auth details. * Python 
  ```python
  1
  response = actions.get_or_create_connected_account(
  2
      connection_name="github-connect",
  3
      identifier="user_123"
  4
  )
  5
  connected_account = response.connected_account
  6
  print(f"Status: {connected_account.status}")
  ```
 * Node.js 
  ```typescript
  1
  const response = await actions.getOrCreateConnectedAccount({
  2
    connectionName: 'github-connect',
  3
    identifier: 'user_123',
  4
  });
  5


  6
  console.log('Status:', response.connectedAccount?.status);
  ```
 ## Handle inactive accounts [Section titled “Handle inactive accounts”](#handle-inactive-accounts) When a connected account isn’t `ACTIVE`, generate a new authorization link and send it to the user. The link opens a **Hosted Page**, a Scalekit-hosted UI that adapts automatically based on the connection’s auth type: * **OAuth connectors**: presents the provider’s OAuth consent screen * **API key, basic auth, or other connectors**: presents a form to collect the required credentials Your code is the same regardless of connector type. Scalekit determines the right flow based on the connection configuration. * Python 
  ```python
  1
  if connected_account.status != "ACTIVE":
  2
      link_response = actions.get_authorization_link(
  3
          connection_name="github-connect",
  4
          identifier="user_123"
  5
      )
  6
      # Redirect or send link_response.link to the user
  ```
 * Node.js 
  ```typescript
  1
  import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb';
  2


  3
  if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
  4
    const linkResponse = await actions.getAuthorizationLink({
  5
      connectionName: 'github-connect',
  6
      identifier: 'user_123',
  7
    });
  8
    // Redirect or send linkResponse.link to the user
  9
  }
  ```
 ## Detect when re-authentication is needed [Section titled “Detect when re-authentication is needed”](#detect-when-re-authentication-is-needed) A connected account can leave the `ACTIVE` state on its own, with no action from you or the user. When that happens, the next tool call fails until the user re-authorizes. To catch it early, subscribe to the `connected_account.status_updated` webhook instead of waiting for a failed call. ### Common causes [Section titled “Common causes”](#common-causes) OAuth connected accounts most often move to `EXPIRED` for reasons outside Scalekit’s control: * **The provider revoked the refresh token.** A password change, an admin-initiated token revocation, or a provider security policy invalidates the refresh token, so Scalekit can no longer obtain new access tokens. * **The refresh token expired.** Providers cap refresh-token lifetimes (for example, 30 or 180 days), and the expiry is rarely surfaced in advance. * **No refresh token was issued.** When the connection’s scopes don’t request offline access, the provider returns only a short-lived access token and no refresh token to renew it. * **The provider hit a per-user token limit.** Some providers keep only a fixed number of refresh tokens per user and app, and silently drop the oldest ones when a user reconnects repeatedly. The first two cases require the user to re-authenticate; there is no server-side workaround. The last two are configuration issues you fix on the connection by requesting offline access scopes. ### Subscribe to status changes [Section titled “Subscribe to status changes”](#subscribe-to-status-changes) The `connected_account.status_updated` event fires on every status transition and carries both the new and previous status: connected\_account.status\_updated 
```json
1
{
2
  "spec_version": "1",
3
  "id": "evt_101652975398683158",
4
  "type": "connected_account.status_updated",
5
  "occurred_at": "2025-12-02T06:31:34.895815554Z",
6
  "environment_id": "env_88640229614813449",
7
  "object": "ConnectedAccount",
8
  "data": {
9
    "id": "ca_133400349586228019",
10
    "identifier": "john@acmecorp.com",
11
    "connection_id": "conn_133400101014995480",
12
    "connection_name": "github-connect",
13
    "provider": "GITHUB",
14
    "authorization_type": "OAUTH",
15
    "status": "EXPIRED",
16
    "old_status": "ACTIVE"
17
  }
18
}
```
 Because the event covers every transition, filter on the change you care about. To alert users only when an active account needs re-authorization, act on `old_status` `ACTIVE` moving to `status` `EXPIRED`: 
```js
1
// The event fires for all transitions (for example, PENDING_AUTH to ACTIVE).
2
// Filter to the one that requires user action, or you will notify on noise.
3
if (event.data.old_status === 'ACTIVE' && event.data.status === 'EXPIRED') {
4
  // Generate a fresh authorization link and notify the user
5
}
```
 When you receive this event, [generate a new authorization link](#handle-inactive-accounts) and prompt the user to reconnect. See the full payload for the [`connected_account.status_updated` event](/apis/#webhook/connectedaccountstatusupdated) in the API reference. ## List connected accounts [Section titled “List connected accounts”](#list-connected-accounts) 
```typescript
1
const listResponse = await actions.listConnectedAccounts({
2
  connectionName: 'github-connect',
3
});
4
console.log('Connected accounts:', listResponse);
```
 ## Delete a connected account [Section titled “Delete a connected account”](#delete-a-connected-account) Deleting a connected account removes the user’s credentials and authorization state. The user must re-authenticate to reconnect. 
```typescript
1
await actions.deleteConnectedAccount({
2
  connectionName: 'github-connect',
3
  identifier: 'user_123',
4
});
```
 ## Update OAuth scopes [Section titled “Update OAuth scopes”](#update-oauth-scopes) Scopes apply to OAuth connectors only. For non-OAuth connectors (API key, basic auth, and similar), generate a new authorization link and the hosted page will collect updated credentials. To request additional OAuth scopes from an existing connected account: 1. Update the connection’s scopes in **AgentKit** > **Connections** > **Edit**. 2. Generate a new authorization link for the user. 3. The user completes the OAuth consent screen, approving the updated scopes. 4. Scalekit updates the connected account with the new token set.

---
# DOCUMENT BOUNDARY
---

# Configure a connection

> Set up a connection in the Scalekit Dashboard to authorize your agent to use a third-party connector on behalf of your users.

A **connection** is a configuration you create once in the Scalekit Dashboard. It holds everything Scalekit needs to interact with a connector’s API: OAuth app credentials, scopes, redirect URIs, and so on. One connection serves all your users. Users don’t configure connections. When a user authenticates, Scalekit creates a **connected account**, the per-user record that links their identity to a connection and holds their tokens. ## What the connection form asks for [Section titled “What the connection form asks for”](#what-the-connection-form-asks-for) The connection form adapts to what the connector requires. Two things determine how much you need to configure: * **OAuth-based connectors** require the most setup. You register an OAuth app with the provider, then enter those credentials into Scalekit. * **Non-OAuth connectors** (API key, basic auth, key pairs, and similar) require minimal developer setup (usually just a name). The user provides their own credentials when they create their connected account. The sections below walk through both patterns. ## Set up an OAuth connection [Section titled “Set up an OAuth connection”](#set-up-an-oauth-connection) OAuth connections require you to create an OAuth app with the provider and link it to Scalekit. Scalekit provides the Redirect URI; you bring the Client ID and Client Secret. 1. ### Open the connection form [Section titled “Open the connection form”](#open-the-connection-form) In the Scalekit Dashboard, go to **AgentKit** > **Connections** and click **Add connection**. Select the connector you want to configure. The form shows the fields that connector requires. 2. ### Copy the redirect URI [Section titled “Copy the redirect URI”](#copy-the-redirect-uri) Scalekit generates a **Redirect URI** for this connection. Copy it; you’ll need it in the next step. This URI is where the provider sends the user after they complete the OAuth consent screen. Scalekit handles the callback automatically. 3. ### Register your OAuth app with the provider [Section titled “Register your OAuth app with the provider”](#register-your-oauth-app-with-the-provider) In the provider’s developer console (GitHub, Salesforce, Google, etc.), create an OAuth app and add Scalekit’s Redirect URI to the list of authorized redirect URIs. The provider will give you a **Client ID** and **Client Secret** after registration. Redirect URI must match exactly The URI in the provider’s console must match what Scalekit shows character-for-character, including trailing slashes. A mismatch causes the OAuth flow to fail with a redirect\_uri\_mismatch error. 4. ### Enter your credentials [Section titled “Enter your credentials”](#enter-your-credentials) Back in the Scalekit Dashboard, enter the **Client ID** and **Client Secret** from the provider. 5. ### Configure scopes [Section titled “Configure scopes”](#configure-scopes) Select the scopes your agent needs. Scopes define what your agent can do on the user’s behalf: for example, `read:email` or `repo`. 6. ### Save the connection [Section titled “Save the connection”](#save-the-connection) Click **Save**. The connection is now active and ready for connected accounts to be created against it. ## Set up a non-OAuth connection [Section titled “Set up a non-OAuth connection”](#set-up-a-non-oauth-connection) For connectors that use API keys, basic auth, key pairs, or similar, the connection form asks for very little. In many cases, you only need to give the connection a name. The user provides their own credentials (their API key, account details, or private key) when they create a connected account. Scalekit collects those credentials through the connected account form and stores them securely. 1. Go to **AgentKit** > **Connections** and click **Add connection** 2. Select the connector 3. Enter a **Connection name**: this identifies the connection in the dashboard and in your code 4. Click **Save** When a connected account is created for this connection, Scalekit presents the user with a form that collects the credentials their specific account requires. ## Create multiple connections for the same connector [Section titled “Create multiple connections for the same connector”](#create-multiple-connections-for-the-same-connector) You can create more than one connection for the same connector. This is useful when: * Different groups of users need different scopes * You want to maintain separate OAuth apps for staging and production * You’re integrating with multiple instances of the same service (for example, two different Salesforce orgs) Each connection has its own name, which you use to identify it in API calls and in the dashboard. ## Common scenarios [Section titled “Common scenarios”](#common-scenarios)

---
# DOCUMENT BOUNDARY
---

# Manage encryption keys

> Protect data at rest with Scalekit managed keys or bring your own from a cloud Key Management Service (KMS).

Scalekit automatically protects data at rest with encryption keys. You can use Scalekit-managed keys or bring your own from a cloud Key Management Service (KMS) provider if your compliance policy requires you to own and control the root key. This guide shows you how to view and manage keys in the dashboard and set up Bring Your Own Key (BYOK) with GCP Cloud KMS. ## Key types | Type | Description | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- | | **Scalekit managed Data Encryption Key (DEK)** | Scalekit generates and manages the key. No setup required. | | **Bring your own key (BYOK)** | You provide a key from your own KMS. You own the key lifecycle, including rotation and revocation. | ## Key states | State | Description | | ---------- | ----------------------------------------------------------------------------------------------- | | Staged | Created, not yet in use. No data is encrypted with it. | | Primary | The active key. All new encryption operations use it. | | Deprecated | Replaced by a newer key. Existing records may still reference it until re-encryption completes. | ## Manage keys Go to **Settings** and open the **Encryption keys** tab. 1. **Create a key** Click **Create New Key** and select a provider: * **Scalekit Managed DEK**: Scalekit generates and manages the key. Click **Create**. * **BYOK - GCP Cloud KMS**: Complete [Set up BYOK with GCP KMS](#set-up-byok-with-gcp-kms) first to create the GCP key and grant access, then enter the key resource name here and click **Create**. The key is created in **Staged** state. 2. **Activate the key** Click **Activate** on a Staged key. The key becomes Primary and Scalekit uses it for all new encryption operations. 3. **Re-encrypt existing data** To apply the new key to existing records, click **Re-encrypt Data**. Scalekit decrypts each existing record with the previous key and re-encrypts it with the new key. ## Set up BYOK with GCP KMS Use BYOK to register an encryption key from Google Cloud KMS that your team owns and controls. Scalekit uses the KMS API for all encrypt and decrypt operations and never stores the key material. You own the key lifecycle BYOK gives you direct control over your encryption key. Scalekit cannot rotate or manage the GCP key on your behalf. If the key is disabled, destroyed, or Identity and Access Management (IAM) access is revoked, Scalekit cannot encrypt new data or decrypt existing records until you restore access. ### Prerequisites * A **Google Cloud project** with the [Cloud KMS API enabled](https://cloud.google.com/kms/docs/create-encryption-keys) * **IAM permissions** to create key rings, keys, and set key-level IAM policies * The **Scalekit service account email**, shown in the Scalekit dashboard when you select BYOK * `gcloud` CLI installed and authenticated, or access to the [GCP Console](https://console.cloud.google.com/security/kms) 1. **Create a key ring** A [key ring](https://cloud.google.com/kms/docs/resource-hierarchy#key_rings) groups encryption keys by location. Key rings cannot be deleted or renamed once created. Choose the name and location carefully. * gcloud CLI 
     ```bash
     1
     gcloud kms keyrings create "scalekit-kms-keyring" \
     2
       --location "global" \
     3
       --project "YOUR-GCP-PROJECT"
     ```
 Replace `YOUR-GCP-PROJECT` with your Google Cloud project ID. * GCP Console 1. Open [**Security > Key management**](https://console.cloud.google.com/security/kms), click **Key rings**. 2. Click **Create key ring**, enter `scalekit-kms-keyring` as the name. 3. Set **Location** to **Global** and click **Create**. 2. **Create an encryption key** Create a symmetric AES-256-GCM key inside the key ring. * gcloud CLI 
     ```bash
     1
     gcloud kms keys create "scalekit-kms-key" \
     2
       --location "global" \
     3
       --keyring "scalekit-kms-keyring" \
     4
       --purpose "encryption" \
     5
       --project "YOUR-GCP-PROJECT"
     ```
 * GCP Console 1. Click the key ring you created, then click **Create key**. 2. Enter `scalekit-kms-key` as the name. 3. Set **Protection level** to **HSM** (recommended) and click **Continue**. 4. Set **Key material** to **HSM-generated** and click **Continue**. 5. Set **Purpose** to **Symmetric encrypt/decrypt** and click **Continue**. 6. Set **Rotation period** per your policy and click **Create**. 3. **Grant Scalekit access to the key** Grant both roles at the key level to limit Scalekit’s IAM access to this specific key. | Role | Purpose | | -------------------------------------------- | ----------------------------------------------- | | `roles/cloudkms.cryptoKeyEncrypterDecrypter` | Encrypt and decrypt the DEK | | `roles/cloudkms.viewer` | Read key metadata for health checks and listing | * gcloud CLI 
     ```bash
     1
     gcloud kms keys add-iam-policy-binding "scalekit-kms-key" \
     2
       --keyring "scalekit-kms-keyring" \
     3
       --location "global" \
     4
       --project "YOUR-GCP-PROJECT" \
     5
       --member "serviceAccount:SCALEKIT-SERVICE-ACCOUNT" \
     6
       --role "roles/cloudkms.cryptoKeyEncrypterDecrypter"
     7


     8
     gcloud kms keys add-iam-policy-binding "scalekit-kms-key" \
     9
       --keyring "scalekit-kms-keyring" \
     10
       --location "global" \
     11
       --project "YOUR-GCP-PROJECT" \
     12
       --member "serviceAccount:SCALEKIT-SERVICE-ACCOUNT" \
     13
       --role "roles/cloudkms.viewer"
     ```
 * GCP Console 1. In the GCP Console, open **Security > Key management**, click **Key rings**, then click the key ring name. 2. Click the key name, then open the **Permissions** tab. 3. Click **Grant access**. A side panel opens. 4. In the **New principals** field, enter the Scalekit service account email. Copy it from **Settings > Encryption keys > Create New Key > BYOK - GCP Cloud KMS** in the Scalekit dashboard. 5. In the **Assign Roles** section, select **Cloud KMS CryptoKey Encrypter/Decrypter** from the first **Role** dropdown. 6. Click **+ Add another role** and select **Cloud KMS Viewer**. 7. Click **Save**. The policy update takes effect within a few minutes. 4. **Register the key in Scalekit** * In the Scalekit dashboard, go to **Settings** and open the **Encryption keys** tab. * Click **Create New Key** and select **BYOK - GCP Cloud KMS**. * Copy the Scalekit service account email shown in the modal. You need it for step 3 (grant Scalekit access to the key) if you have not granted IAM access yet. * Enter the fully-qualified GCP key resource name: 
   ```plaintext
   1
   projects/YOUR-GCP-PROJECT/locations/global/keyRings/scalekit-kms-keyring/cryptoKeys/scalekit-kms-key
   ```
 To retrieve the exact name from the CLI: 
   ```bash
   1
   gcloud kms keys describe "scalekit-kms-key" \
   2
     --keyring "scalekit-kms-keyring" \
   3
     --location "global" \
   4
     --project "YOUR-GCP-PROJECT" \
   5
     --format="value(name)"
   ```
 * Click **Create**. The key is created in **Staged** state. 5. **Activate the key** Click **Activate** on the staged key. The key becomes Primary and Scalekit uses it for all new encryption operations. Activation is permanent Once activated, you cannot deactivate the key without creating and activating a new key. Confirm your IAM grants are in place before activating. 6. **Re-encrypt existing data** Activation covers new writes automatically. Click **Re-encrypt Data** to migrate existing records. Scalekit decrypts each record with the previous key and re-encrypts it with the new key. ## Monitor with audit logs Cloud KMS logs every cryptographic operation to [Cloud Audit Logs](https://cloud.google.com/kms/docs/audit-logging). Use this filter in **Cloud Logging** to see all encrypt, decrypt, and key events for your key: 
```plaintext
1
resource.type="cloudkms_cryptokey"
```
 ## Fix common errors

---
# DOCUMENT BOUNDARY
---

# Connect Hermes to AgentKit

> Connect Hermes to GitHub, Gmail, and Slack through Scalekit. Install the skill, set credentials, and run one tool call.

[Hermes](https://hermes-agent.nousresearch.com/docs/) is the self-improving AI agent from Nous Research. Hermes runs where you put it: a laptop, a small VPS, or a GPU cluster. You reach Hermes from the command line, or from a messaging app such as Slack or Telegram, and Hermes also runs work on a cron schedule. Hermes ships with 60+ built-in tools, and the built-in tools stop at the edge of your machine. A Hermes agent that reads your Gmail, posts to your Slack, or opens a GitHub pull request needs an access token for each app. Every access token belongs to one user. Scalekit holds the connected account for that user, stores the access token, and refreshes the access token. Hermes reaches Scalekit through a **skill**. A skill is an on-demand instruction set plus scripts, and Hermes loads a skill from `~/.hermes/skills/` when a chat calls for one. The skill tells Hermes how to find the Scalekit connection, how to check that the user finished auth, and how to call the tool with the stored token. The steps below install the skill. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * [Hermes Agent](https://hermes-agent.nousresearch.com/docs/getting-started/quickstart) installed * A Scalekit account with AgentKit enabled: [sign up at app.scalekit.com](https://app.scalekit.com) * At least one connection in **Dashboard > AgentKit > Connections**. Create the connection before you ask Hermes to use the app. See [connections](/agentkit/connectors/). * [`uv`](https://docs.astral.sh/uv/) on your `PATH` ## How the skill works [Section titled “How the skill works”](#how-the-skill-works) The skill runs the following loop when you name an app: 1. The skill looks up the Scalekit connection you already created for [GitHub](/agentkit/connectors/github/), [Gmail](/agentkit/connectors/gmail/), or another app. 2. The skill checks the user’s connected account. `ACTIVE` means auth is complete and Scalekit holds a token. 3. The skill returns a magic link when the connected account is not `ACTIVE`. 4. The skill fetches the tool schema, calls the tool, and returns the result. 5. The skill calls the Scalekit HTTP proxy when the connector has no named tool. A magic link is a one-time URL. The hosted page shows OAuth consent, or an API-key form. ## Get started [Section titled “Get started”](#get-started) Using a coding agent?Copy Hermes prompt 1. ### Install the skill [Section titled “Install the skill”](#install-the-skill) Install `hermes-delegated-auth` from authstack: 
   ```bash
   hermes skills install scalekit-inc/authstack/kits/agentkit/host/hermes-delegated-auth
   ```
 Confirm the skill is enabled: 
   ```bash
   hermes skills list
   ```
 
   ```txt
   │ hermes-delegated-auth │          │ local  │ local │ enabled │
   ```
 Install the Python dependencies: 
   ```bash
   cd "${HERMES_HOME:-$HOME/.hermes}/skills/hermes-delegated-auth"
   uv sync
   ```
 New chats load `/hermes-delegated-auth`. Run `/reset` in a chat that is already open. `HERMES_HOME` changes the skill path. The commands on this page use `~/.hermes`. Install from the authstack path A raw `SKILL.md` URL leaves out `scripts/`, and the skill then fails at run time. The `integrate-agentkit-host` skill is for coding agents, not for Hermes. 2. ### Configure credentials [Section titled “Configure credentials”](#configure-credentials) Put only Scalekit client credentials in `~/.hermes/.env`. Scalekit stores and refreshes the provider tokens for GitHub, Gmail, and Slack. Provider tokens never belong in a Hermes file. \~/.hermes/.env 
   ```bash
   1
   SCALEKIT_CLIENT_ID=skc_your_client_id
   2
   # Threat: a leaked secret lets anyone call tools as any ACTIVE identifier.
   3
   SCALEKIT_CLIENT_SECRET=your_client_secret
   4
   SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.cloud
   5
   SCALEKIT_IDENTIFIER=usr_8f3a2c
   ```
 | Parameter | Description | | -------------------------- | -------------------------------------- | | `SCALEKIT_CLIENT_ID` | Your Scalekit client ID Required | | `SCALEKIT_CLIENT_SECRET` | Your Scalekit client secret Required | | `SCALEKIT_ENVIRONMENT_URL` | Your Scalekit environment URL Required | | `SCALEKIT_IDENTIFIER` | Default user the host acts as Required | Copy the client ID, client secret, and environment URL from **Dashboard > Developers > Settings > API Credentials**. `SCALEKIT_IDENTIFIER` is not a dashboard credential. Pick an opaque id that only your system knows, for example `usr_8f3a2c`. Every `tool_exec.py` command needs `SCALEKIT_IDENTIFIER`, including `--list-connections`. Keep the identifier unguessable An email address or a first name is guessable. `SCALEKIT_CLIENT_SECRET` lets anyone call tools as any `ACTIVE` identifier, so a guessable identifier widens the damage. Add [user verification](/agentkit/user-verification/) in a multi-user product so the wrong person cannot activate the slot. 3. ### Ask Hermes to act [Section titled “Ask Hermes to act”](#ask-hermes-to-act) Start a chat and ask for a real action. Hermes acts as `SCALEKIT_IDENTIFIER` by default, and Hermes passes `--identifier` to the skill when you name another user in the prompt. * GitHub 
     ```txt
     You: Who am I on GitHub?
     ```
 Hermes loads the skill and runs these steps: 1. Hermes looks up the GitHub connection. 2. Hermes checks that the connected account is `ACTIVE`, and returns a magic link when the account is not. 3. Hermes fetches the tool schema. 4. Hermes calls the tool and returns your GitHub login. * Gmail 
     ```txt
     You: Show me my latest unread emails
     ```
 Hermes runs these steps: 1. Hermes looks up the Gmail connection. 2. Hermes returns a magic link when you have not authorized Gmail yet. 3. Hermes fetches the tool schema. 4. Hermes returns the mail. * Notion 
     ```txt
     You: Read my Notion page https://notion.so/My-Page-abc123
     ```
 Hermes runs these steps: 1. Hermes looks up the Notion connection. 2. Hermes returns a magic link when you have not authorized Notion yet. 3. Hermes fetches the page tool schema. 4. Hermes returns the page content. * Slack (as a user) 
     ```txt
     You: As identifier usr_8f3a2c, list my unread Slack DMs
     ```
 Hermes runs these steps: 1. Hermes looks up the Slack connection. 2. Hermes returns a magic link when the Slack connected account is not `ACTIVE`. 3. Hermes fetches the Slack tool schema. 4. Hermes returns the direct messages (DMs) as `usr_8f3a2c`. Create the Slack connection with **User scope** for the prompt above. A Slack connection with **Bot scope** acts as your Slack app instead of acting as the person. See the [Slack connector](/agentkit/connectors/slack/). * Google Calendar 
     ```txt
     You: Create an out-of-office event tomorrow on the calendar for usr_8f3a2c
     ```
 Hermes runs these steps: 1. Hermes looks up the Google Calendar connection for `usr_8f3a2c`. 2. Hermes returns a magic link when the connected account is not `ACTIVE`. 3. Hermes calls the create-event tool. 4. Scalekit writes the event with the `usr_8f3a2c` token. Name the skill in the prompt to force the same path: 
   ```txt
   /hermes-delegated-auth who am I on GitHub?
   ```
 ## Verify it works [Section titled “Verify it works”](#verify-it-works) Confirm all of the following: * The skill is listed (`hermes skills list` or `/skills`) as `hermes-delegated-auth` * The connected account is `ACTIVE` after you finish the magic link * Hermes returns data from the provider (the GitHub login, or unread mail) Open the magic link again and retry the same prompt if the account stays inactive. ## Use Slack as a bot or as a user [Section titled “Use Slack as a bot or as a user”](#use-slack-as-a-bot-or-as-a-user) Slack issues two kinds of token, and the token decides whose name appears on a message. A bot token posts as your Slack app. A user token posts as the person who authorized the app. Authorizing the Hermes gateway grants a bot token, so the gateway alone cannot post as a person. | Job | Use | | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Chat with the agent in a channel or DM | Hermes Slack **gateway**. Bot tokens (`xoxb-` + `xapp-`) in `~/.hermes/.env`. See the [Hermes Slack setup](https://hermes-agent.nousresearch.com/docs/user-guide/messaging/slack). | | Read private history, post, or act as a user | Scalekit Slack connection created with **User scope**. See the [Slack connector](/agentkit/connectors/slack/). | The gateway bot is a channel into the agent. The gateway bot is not `usr_8f3a2c`. Always-on hosts use both identities. The gateway hears the channel. Scalekit acts as the user. ## Run jobs on a schedule [Section titled “Run jobs on a schedule”](#run-jobs-on-a-schedule) Attach the skill to a Hermes cron job. Each fire is a fresh session. The skill uses Scalekit client credentials. You do not mint a session token. 
```bash
hermes cron create "0 9 * * *" "List unread emails for usr_8f3a2c and post a 5-line summary" --skill hermes-delegated-auth
```
 Or in chat: 
```txt
/cron add "every weekday at 9am" "List unread emails for usr_8f3a2c and post a 5-line summary" --skill hermes-delegated-auth
```
 The connected account must already be `ACTIVE`. Cron cannot click a magic link. Leave the gateway running on a headless host. A new magic link can then land in Slack or Telegram. Do not put Gmail or Calendar refresh tokens in `~/.hermes/.env`. ## Choose how Hermes reaches Scalekit [Section titled “Choose how Hermes reaches Scalekit”](#choose-how-hermes-reaches-scalekit) Three patterns connect Hermes to Scalekit. Pick the one that matches your host. **Pattern A: delegated skill.** The default for Hermes. The host holds Scalekit client credentials, and each turn names an identifier. No token sits on the host, so nothing expires. **Pattern B: Virtual MCP on the host.** A Virtual MCP server exposes only the tools you list. Hermes reads one bearer token, so the host acts as one operator. You mint the token and reload the host. **Pattern C: Virtual MCP in your app.** Your application mints a token before each agent run and passes it to the agent framework. Claude Managed Agents, Mastra, and CrewAI use Pattern C. | Question | A: delegated skill | B: Virtual MCP on the host | C: Virtual MCP in your app | | ----------------------- | -------------------------------- | --------------------------------- | ---------------------------- | | Who runs the agent | Hermes | Hermes | your app | | How many end users | many; switch with `--identifier` | one operator | many | | Credential on the host | Scalekit client ID and secret | one session-token bearer | none | | Anything expires? | no | yes, about 1 hour by default | yes, per run | | Who mints a replacement | nobody; there is no token | you, on a schedule, then reload | your code, before each run | | Tool scoping | the full connector catalog | only the tools in the config | only the tools in the config | | Best for | multi-user hosts and cron | a scoped, single-operator gateway | short agent runs | The rest of this page covers Pattern A. For Pattern B, see [Run Virtual MCP on a Hermes host](#run-virtual-mcp-on-a-hermes-host). For Pattern C, see [Set up and connect a Virtual MCP server](/agentkit/mcp/configure-mcp-server/). ## Run Virtual MCP on a Hermes host [Section titled “Run Virtual MCP on a Hermes host”](#run-virtual-mcp-on-a-hermes-host) Draft — not live-verified This flow has not been live-verified yet. Confirm the remint and `/reload-mcp` loop on a Hermes host before you treat this section as production guidance. This is the long-running host setup. One operator. One bearer. You remint. Use this when you want a scoped tool list on a single-operator Hermes gateway. Create the Virtual MCP config once. Mint a session token with `create_session_token`. Put the token in Hermes `config.yaml`. Reload the host before the token expires. 1. ### Create the Virtual MCP config once [Section titled “Create the Virtual MCP config once”](#create-the-virtual-mcp-config-once) Create the server once per operator role. Save the static `mcp_server_url`. Do not regenerate the config on each remint. See [Set up and connect a Virtual MCP server](/agentkit/mcp/configure-mcp-server/). 2. ### Mint a session token [Section titled “Mint a session token”](#mint-a-session-token) Call `create_session_token` for one identifier. Set `expiry` above your reload interval. 
   ```python
   from datetime import timedelta


   token_response = scalekit_client.actions.mcp.create_session_token(
       mcp_config_id=config_id,
       identifier="usr_8f3a2c",
       expiry=timedelta(hours=2),
   )


   token = token_response.token
   ```
 `create_session_token` is the remint call. Call it again whenever you need a new token. 3. ### Put the token in Hermes config [Section titled “Put the token in Hermes config”](#put-the-token-in-hermes-config) Write the token to `SCALEKIT_MCP_SESSION_TOKEN` in `~/.hermes/.env`. Point `~/.hermes/config.yaml` at the static URL and that env var. \~/.hermes/config.yaml 
   ```yaml
   1
   mcp_servers:
   2
     scalekit:
   3
       url: ""
   4
       headers:
   5
         Authorization: "Bearer ${SCALEKIT_MCP_SESSION_TOKEN}"
   ```
 Do not set `auth: oauth`. A Scalekit Virtual MCP server takes a bearer token, not MCP OAuth. Do not run `hermes mcp login` against this URL. 4. ### Reload Hermes [Section titled “Reload Hermes”](#reload-hermes) Restart Hermes, or run `/reload-mcp` so Hermes rereads the bearer. 5. ### Remint on a schedule [Section titled “Remint on a schedule”](#remint-on-a-schedule) On a cron, mint a new token, write `SCALEKIT_MCP_SESSION_TOKEN`, then run `/reload-mcp`. Repeat before the token expires. Set `expiry` above that interval. An expired bearer fails at the next tool call, not at startup. One Hermes host is one operator. Mint per-end-user tokens in your own application. See [Set up and connect a Virtual MCP server](/agentkit/mcp/configure-mcp-server/). ## Avoid these mistakes [Section titled “Avoid these mistakes”](#avoid-these-mistakes) * Do not put provider tokens in `~/.hermes/.env`. Put only Scalekit credentials there. * Do not set `SCALEKIT_IDENTIFIER` to an email or another guessable value. * Do not use the bundled Google Workspace skill (`~/.hermes/google_token.json`) if AgentKit owns the Google user. `~/.hermes/google_token.json` is one laptop login, not a per-user identifier. * Do not run `hermes mcp login` against Scalekit Virtual MCP (a Scalekit MCP URL plus a session token). Virtual MCP uses a static bearer session token, and a static bearer token is not MCP OAuth. * Do not treat the Slack bot token as “send as usr\_8f3a2c”. * Do not use one Hermes host as a multi-tenant identity provider. One gateway is one operator. Switch identifiers on the same host with `--identifier`. Mint per-end-user Virtual MCP session tokens in your own application, not inside Hermes. ## Next steps [Section titled “Next steps”](#next-steps) [Browse connections](/agentkit/connectors/)See supported connectors in the Scalekit dashboard [Authorize a user](/agentkit/tools/authorize/)How magic links and connected accounts work [Example repo](https://github.com/scalekit-developers/hermes-agentkit-example)Runnable companion on scalekit-developers ## Common scenarios [Section titled “Common scenarios”](#common-scenarios)

---
# DOCUMENT BOUNDARY
---

# Set up and connect a Virtual MCP server

> Create a Virtual MCP Server, verify user connections, mint session tokens, and connect your agent using bearer auth.

## Prerequisites [Section titled “Prerequisites”](#prerequisites) Before creating a Virtual MCP Server, configure the connections you want to expose. Each `connection_name` you reference must already exist in **AgentKit > Connections**. See [Configure a connection](/agentkit/connections/) if you haven’t done this yet. ## Create a Virtual MCP server [Section titled “Create a Virtual MCP server”](#create-a-virtual-mcp-server) Create the server once per agent role — not once per user. The response includes a static `mcp_server_url` you reuse for every user and every session. 
```python
1
import os
2
from scalekit import ScalekitClient
3
from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping
4


5
scalekit_client = ScalekitClient(
6
    env_url=os.environ["SCALEKIT_ENV_URL"],
7
    client_id=os.environ["SCALEKIT_CLIENT_ID"],
8
    client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
9
)
10


11
vmcp_response = scalekit_client.actions.mcp.create_config(
12
    name="email-calendar-agent",
13
    connection_tool_mappings=[
14
        McpConfigConnectionToolMapping(
15
            connection_name="gmail",
16
            tools=["gmail_fetch_mails"],
17
        ),
18
        McpConfigConnectionToolMapping(
19
            connection_name="googlecalendar",
20
            tools=[
21
                "googlecalendar_list_events",
22
                "googlecalendar_create_event",
23
            ],
24
        ),
25
    ],
26
)
27


28
config_id = vmcp_response.config.id
29
mcp_server_url = vmcp_response.config.mcp_server_url
```
 Save `config_id` and `mcp_server_url`. You pass these to every agent session. **Selecting tools**: Each `McpConfigConnectionToolMapping` controls which tools from a connection appear on the server. Omit `tools` to expose all tools for that connection. To find available tool names, browse **AgentKit > Catalog** or open the connection from **AgentKit > Connections**. ## Connect an agent [Section titled “Connect an agent”](#connect-an-agent) Run these steps before each agent session. 1. ## Check that connections are active [Section titled “Check that connections are active”](#check-that-connections-are-active) Verify all connections are still active for this user before minting a token. OAuth credentials can expire or be revoked at any time. 
   ```python
   1
   accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts(
   2
       config_id=config_id,
   3
       identifier="user_123",      # your app's unique identifier for this user
   4
       include_auth_link=True,     # include re-auth URLs for any inactive connections
   5
   )
   6


   7
   for account in accounts_response.connected_accounts:
   8
       if account.connected_account_status != "ACTIVE":
   9
           print(f"{account.connection_name} needs auth: {account.authentication_link}")
   ```
 `identifier` is any string that uniquely identifies a user in your system — an email, user ID, or UUID. Use the same value consistently across all calls. If any connection is not `"ACTIVE"`, surface the `authentication_link` to the user before proceeding. See [Authorize user connections](/agentkit/tools/authorize/). 2. ## Mint a session token [Section titled “Mint a session token”](#mint-a-session-token) Mint a fresh token before every agent run. Never reuse a token from a previous session. 
   ```python
   1
   from datetime import timedelta
   2


   3
   token_response = scalekit_client.actions.mcp.create_session_token(
   4
       mcp_config_id=config_id,
   5
       identifier="user_123",
   6
       expiry=timedelta(hours=1),
   7
   )
   8


   9
   token = token_response.token
   ```
 Set `expiry` longer than the expected agent run duration. For a task that typically takes 20 minutes, a 30-minute expiry is sufficient. 3. ## Pass the token to your agent [Section titled “Pass the token to your agent”](#pass-the-token-to-your-agent) Pass `mcp_server_url` and the session token to your agent framework using bearer auth. 
   ```python
   1
   mcp_server = {
   2
       "url": mcp_server_url,
   3
       "headers": {"Authorization": f"Bearer {token}"},
   4
   }
   ```
 How you register the MCP server depends on your framework. For a complete end-to-end example using Claude Managed Agents — including vault-based auth injection and response streaming — see [Claude Managed Agents](/agentkit/examples/claude-managed-agents/). ## Manage servers [Section titled “Manage servers”](#manage-servers) **List servers** 
```python
1
configs = scalekit_client.actions.mcp.list_configs()
2
for config in configs.configs:
3
    print(config.id, config.name, config.mcp_server_url)
4


5
# Filter by name
6
configs = scalekit_client.actions.mcp.list_configs(filter_name="email-calendar-agent")
```
 **Update a server** You can update `description` or `connection_tool_mappings` on an existing server. Only do this when no agent sessions are actively running — updating mid-session can cause tools to become unavailable. For significant changes, create a new server and swap the `mcp_server_url` in your agent definition so existing sessions complete cleanly. 
```python
1
scalekit_client.actions.mcp.update_config(
2
    config_id=config_id,
3
    connection_tool_mappings=[
4
        McpConfigConnectionToolMapping(
5
            connection_name="gmail",
6
            tools=["gmail_fetch_mails", "gmail_send_mail"],
7
        ),
8
        McpConfigConnectionToolMapping(
9
            connection_name="googlecalendar",
10
            tools=["googlecalendar_create_event", "googlecalendar_list_events"],
11
        ),
12
    ],
13
)
```
 **Delete a server** 
```python
1
scalekit_client.actions.mcp.delete_config(config_id=config_id)
```
 Deleting a server immediately invalidates the `mcp_server_url`. Any agent connected to that URL loses tool access. Confirm no active sessions are running before deleting.

---
# DOCUMENT BOUNDARY
---

# OpenClaw skill

> Connect OpenClaw agents to third-party services through Scalekit. Supports LinkedIn, Notion, Slack, Gmail, and 200+ connectors.

Use the Scalekit AgentKit skill for [OpenClaw](https://github.com/scalekit-inc/openclaw-skill) to let your AI agents execute actions on third-party services directly from conversations. Search LinkedIn, read Notion pages, send Slack messages, query Snowflake, and more, all through Scalekit Connect without storing tokens or API keys in your agent. Security considerations for AI agents Scalekit stores tokens and API keys securely with full audit logging. OpenClaw, like all AI agent frameworks, is vulnerable to prompt injection and other agent-level attacks. Follow security best practices to protect your instance. When you ask Claude to interact with a third-party service, the skill: * Finds the configured connector in Scalekit (e.g., [Gmail connection setup](/agentkit/connectors/gmail/)) and identifies which connection to use based on the requested action * Checks if the connection is active. For OAuth connections, it generates a magic link for new authorizations. For API key connections, it provides Dashboard guidance for setup * Retrieves available tools and their parameter schemas for the connector, determining what actions are possible * Calls the right tool with the correct parameters and returns the result to your conversation * If no tool exists for the action, routes the request through Scalekit’s HTTP proxy, making direct API calls on your behalf Your agent never stores tokens or API keys. Scalekit acts as a token vault, managing all OAuth tokens, API keys, and credentials. The skill retrieves only what it needs at runtime, scoped to the requesting user. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * [OpenClaw](https://openclaw.ai) installed and configured * A Scalekit account with AgentKit enabled: [sign up at app.scalekit.com](https://app.scalekit.com) * `python3` and `uv` available in your PATH ## Get started [Section titled “Get started”](#get-started) 1. ## Install the skill [Section titled “Install the skill”](#install-the-skill) Install the skill from ClawHub: 
   ```bash
   clawhub install scalekit-agent-auth
   ```
 2. ## Configure credentials [Section titled “Configure credentials”](#configure-credentials) Add your Scalekit credentials to `.env` in your project root: .env 
   ```bash
   1
   TOOL_CLIENT_ID=skc_your_client_id      # Your Scalekit client ID
   2
   TOOL_CLIENT_SECRET=your_client_secret  # Your Scalekit client secret
   3
   TOOL_ENV_URL=https://your-env.scalekit.cloud  # Your Scalekit environment URL
   4
   TOOL_IDENTIFIER=your_default_user_identifier  # Default user context for tool calls
   ```
 | Parameter | Description | | -------------------- | --------------------------------------------------- | | `TOOL_CLIENT_ID` | Your Scalekit client ID Required | | `TOOL_CLIENT_SECRET` | Your Scalekit client secret Required | | `TOOL_ENV_URL` | Your Scalekit environment URL Required | | `TOOL_IDENTIFIER` | Default user context for all tool calls Recommended | Environment variable security Never commit `.env` files to version control. Add `.env` to your `.gitignore` file to prevent accidental exposure of credentials. 3. ## Usage [Section titled “Usage”](#usage) * Gmail 
     ```txt
     You: Show me my latest unread emails
     ```
 OpenClaw will automatically: 1. Look up the `GMAIL` connection 2. Verify it’s active (or generate a magic link to authorize if needed) 3. Fetch the `gmail_list_emails` tool schema 4. Return your latest unread emails * Notion 
     ```txt
     You: Read my Notion page https://notion.so/My-Page-abc123
     ```
 OpenClaw will: 1. Look up the `NOTION` connection 2. If not yet authorized, generate a magic link for you to complete OAuth 3. Fetch the `notion_page_get` tool schema 4. Return the page content ## Supported connectors [Section titled “Supported connectors”](#supported-connectors) Any connector configured in Scalekit works with the OpenClaw skill, including Notion, Slack, Gmail, Google Sheets, GitHub, Salesforce, HubSpot, Linear, Snowflake, Exa, HarvestAPI, and 200+ more. [Browse connections](/agentkit/connectors/)See all supported connectors in the Scalekit dashboard [ClawHub listing](https://clawhub.dev/skills/scalekit-agent-auth)Install scalekit-agent-auth from ClawHub ## Common scenarios [Section titled “Common scenarios”](#common-scenarios)

---
# DOCUMENT BOUNDARY
---

# Node.js SDK

> Install and initialize the Scalekit Node.js SDK for AgentKit.

Install the Node.js SDK, create a `ScalekitClient`, then use the sidebar clients for AgentKit. * **Connected accounts** (`scalekit.actions`) — connect end-user accounts and execute tools * **Tool calling** (`scalekit.tools`) — raw tool definitions for custom adapters * **Error handling** — typed exceptions for API failures ## Install [Section titled “Install”](#install) 
```bash
1
npm install @scalekit-sdk/node
```
 ## Initialize [Section titled “Initialize”](#initialize) 
```ts
import { ScalekitClient } from '@scalekit-sdk/node'


// Security: load credentials from environment variables — never hard-code secrets
const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENVIRONMENT_URL!,
  process.env.SCALEKIT_CLIENT_ID!,
  process.env.SCALEKIT_CLIENT_SECRET!
)
```
 ## Next steps [Section titled “Next steps”](#next-steps) 1. [Connected accounts](/agentkit/sdks/node/actions/) — authorization links, connected accounts, `executeTool` 2. [Tool calling](/agentkit/sdks/node/tools/) — list tools for custom adapters 3. [Error handling](/agentkit/sdks/node/errors/) — catch `ScalekitNotFoundException` and related types

---
# DOCUMENT BOUNDARY
---

# Connected accounts

> Connect accounts, start auth, and execute tools with scalekit.actions

`scalekit.actions` is the primary AgentKit client for connecting end-user accounts, starting OAuth, and executing tools on their behalf. **Common path:** create or look up a connected account → get an authorization link → verify the user after redirect → run tools with `executeTool`. For raw tool schemas used by custom adapters, see [Tool calling](/agentkit/sdks/node/tools/). For exception types, see [Error handling](/agentkit/sdks/node/errors/). ### verifyConnectedAccountUser [Section titled “verifyConnectedAccountUser”](#verifyconnectedaccountuser) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### listConnectedAccounts [Section titled “listConnectedAccounts”](#listconnectedaccounts) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### executeTool [Section titled “executeTool”](#executetool) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### getAuthorizationLink [Section titled “getAuthorizationLink”](#getauthorizationlink) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### listConnections [Section titled “listConnections”](#listconnections) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### deleteConnectedAccount [Section titled “deleteConnectedAccount”](#deleteconnectedaccount) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### getConnectedAccount [Section titled “getConnectedAccount”](#getconnectedaccount) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### createConnectedAccount [Section titled “createConnectedAccount”](#createconnectedaccount) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### getOrCreateConnectedAccount [Section titled “getOrCreateConnectedAccount”](#getorcreateconnectedaccount) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### updateConnectedAccount [Section titled “updateConnectedAccount”](#updateconnectedaccount) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts ### request [Section titled “request”](#request) classActionsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/actions.ts

---
# DOCUMENT BOUNDARY
---

# Error handling

> Catch Scalekit exceptions from AgentKit calls and handle not-found, auth, and server failures

AgentKit methods on `scalekit.actions` and `scalekit.tools` throw typed exceptions when the API returns an error. Catch the specific type first, then fall back to the base server exception. ## Catch exceptions [Section titled “Catch exceptions”](#catch-exceptions) 
```ts
import {
  ScalekitNotFoundException,
  ScalekitUnauthorizedException,
  ScalekitForbiddenException,
  ScalekitServerException,
} from '@scalekit-sdk/node'


try {
  const account = await scalekit.actions.getConnectedAccount({
    connectionName: 'gmail',
    identifier: 'user@example.com',
  })
} catch (err) {
  if (err instanceof ScalekitNotFoundException) {
    // No connected account yet — create one or send the user through OAuth
  } else if (err instanceof ScalekitUnauthorizedException) {
    // Invalid or expired client credentials / tokens
  } else if (err instanceof ScalekitForbiddenException) {
    // Caller is authenticated but not allowed for this resource
  } else if (err instanceof ScalekitServerException) {
    // Unexpected API or platform error — log status and code
    console.error(err.message)
  } else {
    throw err
  }
}
```
 ## Exception types [Section titled “Exception types”](#exception-types) | Exception | When it is raised | Typical response | | ------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------- | | `ScalekitNotFoundException` | Resource does not exist (connected account, tool, config) | Create the resource or return a clear not-found to the user | | `ScalekitUnauthorizedException` | Missing or invalid credentials | Refresh tokens or fix client ID/secret | | `ScalekitForbiddenException` | Authenticated but not permitted | Adjust scopes, org, or role | | `ScalekitServerException` | Base class for Scalekit HTTP/API failures | Log, retry when safe, surface a generic error | `ScalekitServerException` is the base type. Prefer checking subclasses first so not-found and auth failures get the right UX. ## Tool execution errors [Section titled “Tool execution errors”](#tool-execution-errors) A failure during `scalekit.tools.executeTool` comes from one of two places, and the fix differs for each: * **The upstream provider rejected the call** (Gmail, Slack, Salesforce, and so on). Scalekit raises a dedicated `ScalekitTool*` exception. The most common is `ScalekitToolUnauthorizedException`, which means the connected account’s provider token was expired or revoked — re-authorize the connected account. Do not change your client credentials. * **Scalekit rejected the call.** A plain `ScalekitUnauthorizedException` (no tool details) means your `client_id`/`client_secret` or Scalekit token is invalid. The SDK already refreshed and retried before surfacing it, so fix the credentials. Each tool exception subclasses its plain counterpart — `ScalekitToolUnauthorizedException` extends `ScalekitUnauthorizedException` — so **catch the tool type first**. Use `isToolException()` to detect any upstream tool failure, and read `toolErrorCode`, `toolErrorMessage`, and `executionId` for logging. handle-tool-errors.ts 
```ts
import {
  ScalekitToolUnauthorizedException,
  ScalekitToolRateLimitException,
  ScalekitUnauthorizedException,
  isToolException,
} from '@scalekit-sdk/node'


try {
  const result = await scalekit.tools.executeTool({
    toolName: 'gmail_send_email',
    identifier: 'user@example.com',
    params: {
      to: 'team@example.com',
      subject: 'Hello from Scalekit',
      body: 'Tool execution succeeded.',
    },
  })
} catch (err) {
  if (err instanceof ScalekitToolUnauthorizedException) {
    // Upstream provider rejected the token — re-authorize the connected account
  } else if (err instanceof ScalekitToolRateLimitException) {
    // Upstream provider rate limit — back off, then retry the tool call
  } else if (err instanceof ScalekitUnauthorizedException) {
    // Scalekit-side credentials are invalid — fix client ID/secret
  } else if (isToolException(err)) {
    // Any other upstream tool failure — inspect the provider's error
    console.error(err.toolErrorCode, err.toolErrorMessage, err.executionId)
  } else {
    throw err
  }
}
```
 | Exception | When it is raised | Typical response | | ----------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | | `ScalekitToolUnauthorizedException` | Upstream provider returned 401 during tool execution | Re-authorize the connected account | | `ScalekitToolForbiddenException` | Upstream provider returned 403 during tool execution | Add the missing provider scope, then re-authorize | | `ScalekitToolRateLimitException` | Upstream provider returned 429 during tool execution | Back off and retry the tool call | | `ScalekitToolException` | Any other upstream provider error during tool execution | Log `toolErrorCode`, `toolErrorMessage`, and `executionId`; surface a clear message | ## Related [Section titled “Related”](#related) * [Connected accounts](/agentkit/sdks/node/actions/) — connect accounts and execute tools * [Tool calling](/agentkit/sdks/node/tools/) — list tool definitions * [Install](/agentkit/sdks/node/) — create the Scalekit client

---
# DOCUMENT BOUNDARY
---

# Tool calling

> List raw tool schemas for custom adapters

`scalekit.tools` returns raw tool schemas so you can build custom agent adapters instead of using `scalekit.actions.executeTool` directly. Use this client when you need tool definitions (name, parameters, connector) for frameworks or your own executor. For connect + execute flows, prefer [Connected accounts](/agentkit/sdks/node/actions/). These methods throw on 4xx/5xx. See [Error handling](/agentkit/sdks/node/errors/). Pick a discovery method: * `listTools` — workspace catalog * `listScopedTools` — tools already bound to one identifier (the list you pass to an LLM) * `listAvailableTools` — tools you can make available for that identifier * `searchTools` — catalog ranked by relevance to a natural-language query, with per-connection readiness ### listTools [Section titled “listTools”](#listtools) classToolsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/tools.ts ### listScopedTools [Section titled “listScopedTools”](#listscopedtools) classToolsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/tools.ts ### listAvailableTools [Section titled “listAvailableTools”](#listavailabletools) classToolsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/tools.ts ### searchTools [Section titled “searchTools”](#searchtools) classToolsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/tools.ts ### executeTool [Section titled “executeTool”](#executetool) classToolsClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/tools.ts Note: Need a tool Scalekit doesn’t provide? See [Build custom tools](/agentkit/tools/custom-tools/) to proxy any provider API through a connected account.

---
# DOCUMENT BOUNDARY
---

# Python SDK

> Install and initialize the Scalekit Python SDK for AgentKit.

Install the Python SDK, create a `ScalekitClient`, then use the sidebar for AgentKit clients. * **Connections** (`scalekit_client.connection`) — create, list, get, and update environment-level connections * **Connected accounts** (`scalekit_client.actions`) — connect end-user accounts and execute tools * **Tool calling** — raw tool definitions for custom adapters * **MCP server**, **Frameworks**, **Request modifiers**, **Custom OAuth** — advanced surfaces * **Error handling** — typed exceptions for API failures ## Install [Section titled “Install”](#install) **Requires Python 3.8 or later.** The public SDK on PyPI does not support Python 3.5–3.7. If you run a legacy Python environment, contact [support](mailto:support@scalekit.com) to discuss alternatives. 
```bash
1
pip install scalekit-sdk-python
```
 ## Initialize [Section titled “Initialize”](#initialize) 
```python
import os
from scalekit import ScalekitClient


scalekit_client = ScalekitClient(
    env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"],
    client_id=os.environ["SCALEKIT_CLIENT_ID"],
    client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
)


actions = scalekit_client.actions
```
 ## Next steps [Section titled “Next steps”](#next-steps) * [Connections](/agentkit/sdks/python/connections/) * [Connected accounts](/agentkit/sdks/python/actions/) * [Tool calling](/agentkit/sdks/python/tools/) * [MCP](/agentkit/sdks/python/mcp/) * [Framework adapters](/agentkit/sdks/python/framework-adapters/) * [Error handling](/agentkit/sdks/python/errors/)

---
# DOCUMENT BOUNDARY
---

# Connected accounts

> Connect accounts, start auth, and execute tools with scalekit.actions

`scalekit.actions` is the primary AgentKit client for connecting end-user accounts, starting OAuth, and executing tools on their behalf. **Common path:** create or look up a connected account → get an authorization link → verify the user after redirect → run tools. For raw tool schemas, see [Tool calling](/agentkit/sdks/python/tools/). For exceptions, see [Error handling](/agentkit/sdks/python/errors/). ### get\_authorization\_link [Section titled “get\_authorization\_link”](#get_authorization_link) classActionsClient ### verify\_connected\_account\_user [Section titled “verify\_connected\_account\_user”](#verify_connected_account_user) classActionsClient ### get\_or\_create\_connected\_account [Section titled “get\_or\_create\_connected\_account”](#get_or_create_connected_account) classActionsClient ### get\_connected\_account [Section titled “get\_connected\_account”](#get_connected_account) classActionsClient ### get\_connected\_account\_details [Section titled “get\_connected\_account\_details”](#get_connected_account_details) classActionsClient ### list\_connected\_accounts [Section titled “list\_connected\_accounts”](#list_connected_accounts) classActionsClient ### create\_connected\_account [Section titled “create\_connected\_account”](#create_connected_account) classActionsClient ### update\_connected\_account [Section titled “update\_connected\_account”](#update_connected_account) classActionsClient ### delete\_connected\_account [Section titled “delete\_connected\_account”](#delete_connected_account) classActionsClient ### execute\_tool [Section titled “execute\_tool”](#execute_tool) classActionsClient ### request [Section titled “request”](#request) classActionsClient

---
# DOCUMENT BOUNDARY
---

# Connections

> Manage environment-level AgentKit connections with scalekit_client.connection

`scalekit_client.connection` manages the environment-level connections that AgentKit connectors run on. A connection holds the OAuth app credentials, scopes, and redirect URI Scalekit uses when your users authorize a connector, and one connection serves every user in that environment. **Common path:** create the connection once → attach OAuth credentials with `update_environment_connection` → connect end-user accounts with [`scalekit_client.actions`](/agentkit/sdks/python/actions/) → run tools. Most teams create connections in the Scalekit Dashboard — see [Configure a connection](/agentkit/connections/). Use these methods when you provision or manage environments in code, such as seeding a new environment from a setup script or CI job. These methods cover environment-level **app** connections (`Flags(is_app=True)`). Organization-scoped SSO connection APIs stay on the [SaaSKit connection reference](/saaskit/sdks/python/connection/). ### create\_environment\_connection [Section titled “create\_environment\_connection”](#create_environment_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### list\_app\_connections [Section titled “list\_app\_connections”](#list_app_connections) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### get\_environment\_connection [Section titled “get\_environment\_connection”](#get_environment_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### update\_environment\_connection [Section titled “update\_environment\_connection”](#update_environment_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ## Next steps [Section titled “Next steps”](#next-steps) * [Connected accounts](/agentkit/sdks/python/actions/) — connect end-user accounts and run tools on their behalf * [Configure a connection](/agentkit/connections/) — create connections in the Scalekit Dashboard

---
# DOCUMENT BOUNDARY
---

# Custom OAuth

> AgentKit custom providers

`actions.providers` manages custom providers used with bring-your-own connectors. Methods take typed request objects and return typed responses. Working end-to-end examples for OAuth, API key, bearer, and other auth types live in the [custom connectors demos](https://github.com/scalekit-inc/python-connect-demos/tree/main/custom-connectors) repo. Use those samples for field-complete setup rather than partial request shapes here. See [Bring your own connector](/agentkit/bring-your-own-connector/overview/) for the product flow. | Method | Purpose | | ------------------------------------------ | ---------------------------------------------------------------------------- | | `actions.providers.create_custom_provider` | Create a custom provider (`CreateCustomProviderRequest`) | | `actions.providers.update_custom_provider` | Partial update (`UpdateCustomProviderRequest`; only non-`None` fields apply) | | `actions.providers.list_providers` | List or filter providers (`ListProvidersRequest`) | | `actions.providers.delete_custom_provider` | Permanent delete by identifier (`DeleteCustomProviderRequest`) | ***

---
# DOCUMENT BOUNDARY
---

# Error handling

> Catch Scalekit exceptions from AgentKit calls and handle not-found, auth, and server failures

AgentKit methods throw typed exceptions when the API returns an error. Catch the specific type first, then fall back to the base server exception. ## Catch exceptions [Section titled “Catch exceptions”](#catch-exceptions) 
```python
from scalekit.common.exceptions import (
    ScalekitNotFoundException,
    ScalekitUnauthorizedException,
    ScalekitForbiddenException,
    ScalekitServerException,
)


try:
    account = scalekit_client.actions.get_connected_account(
        connection_name="gmail",
        identifier="user@example.com",
    )
except ScalekitNotFoundException:
    # No connected account yet — create one or send the user through OAuth
    pass
except ScalekitUnauthorizedException:
    # Invalid or expired client credentials / tokens
    pass
except ScalekitForbiddenException:
    # Caller is authenticated but not allowed for this resource
    pass
except ScalekitServerException as e:
    # Unexpected API or platform error
    print(e.error_code, e.http_status)
```
 ## Exception types [Section titled “Exception types”](#exception-types) | Exception | When it is raised | Typical response | | ------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------- | | `ScalekitNotFoundException` | Resource does not exist (connected account, tool, config) | Create the resource or return a clear not-found to the user | | `ScalekitUnauthorizedException` | Missing or invalid credentials | Refresh tokens or fix client ID/secret | | `ScalekitForbiddenException` | Authenticated but not permitted | Adjust scopes, org, or role | | `ScalekitServerException` | Base class for Scalekit HTTP/API failures | Log, retry when safe, surface a generic error | `ScalekitServerException` is the base type. Prefer checking subclasses first so not-found and auth failures get the right UX. ## Tool execution errors [Section titled “Tool execution errors”](#tool-execution-errors) A failure during `scalekit_client.tools.execute_tool` comes from one of two places, and the fix differs for each: * **The upstream provider rejected the call** (Gmail, Slack, Salesforce, and so on). Scalekit raises a dedicated `ScalekitTool*` exception. The most common is `ScalekitToolUnauthorizedException`, which means the connected account’s provider token was expired or revoked — re-authorize the connected account. Do not change your client credentials. * **Scalekit rejected the call.** A plain `ScalekitUnauthorizedException` (no tool details) means your `client_id`/`client_secret` or Scalekit token is invalid. The SDK already refreshed and retried before surfacing it, so fix the credentials. Each tool exception subclasses both `ScalekitToolException` and its plain counterpart — `ScalekitToolUnauthorizedException` extends `ScalekitUnauthorizedException` — so **catch the tool type first**. Catch the `ScalekitToolException` base to handle any upstream tool failure, and read `tool_error_code`, `tool_error_message`, and `execution_id` for logging. handle\_tool\_errors.py 
```python
from scalekit.common.exceptions import (
    ScalekitToolUnauthorizedException,
    ScalekitToolRateLimitException,
    ScalekitUnauthorizedException,
    ScalekitToolException,
)


try:
    result = scalekit_client.tools.execute_tool(
        tool_name="gmail_send_email",
        identifier="user@example.com",
        params={
            "to": "team@example.com",
            "subject": "Hello from Scalekit",
            "body": "Tool execution succeeded.",
        },
    )
except ScalekitToolUnauthorizedException:
    # Upstream provider rejected the token — re-authorize the connected account
    pass
except ScalekitToolRateLimitException:
    # Upstream provider rate limit — back off, then retry the tool call
    pass
except ScalekitUnauthorizedException:
    # Scalekit-side credentials are invalid — fix client ID/secret
    pass
except ScalekitToolException as e:
    # Any other upstream tool failure — inspect the provider's error
    print(e.tool_error_code, e.tool_error_message, e.execution_id)
```
 | Exception | When it is raised | Typical response | | ----------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | `ScalekitToolUnauthorizedException` | Upstream provider returned 401 during tool execution | Re-authorize the connected account | | `ScalekitToolForbiddenException` | Upstream provider returned 403 during tool execution | Add the missing provider scope, then re-authorize | | `ScalekitToolRateLimitException` | Upstream provider returned 429 during tool execution | Back off and retry the tool call | | `ScalekitToolException` | Base class for any upstream provider error during tool execution | Log `tool_error_code`, `tool_error_message`, and `execution_id`; surface a clear message | ## Related [Section titled “Related”](#related) * [Connected accounts](/agentkit/sdks/python/actions/) — connect accounts and execute tools * [Tool calling](/agentkit/sdks/python/tools/) — list tool definitions * [Install](/agentkit/sdks/python/) — create the Scalekit client

---
# DOCUMENT BOUNDARY
---

# Frameworks

> Adapters for agent frameworks

Framework adapters map Scalekit tools into popular agent frameworks so you can register tools without hand-writing schema conversion. Pick the adapter for your stack, pass the Scalekit client, and register tools on the agent. See [Connected accounts](/agentkit/sdks/python/actions/) for the underlying client and [Error handling](/agentkit/sdks/python/errors/) for exceptions. ### actions.langchain.get\_tools [Section titled “actions.langchain.get\_tools”](#actionslangchainget_tools) classLangChainhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/actions/frameworks/langchain.py

---
# DOCUMENT BOUNDARY
---

# MCP configurations

> Expose AgentKit tools over MCP.

Expose AgentKit tools over MCP so hosts like Claude Desktop or Cursor can call connected-account tools through a standard protocol. Configure an MCP server, attach connected accounts, and issue tokens for clients. See [Error handling](/agentkit/sdks/python/errors/) for API exceptions. ### scalekit\_client.actions.mcp.create\_config [Section titled “scalekit\_client.actions.mcp.create\_config”](#scalekit_clientactionsmcpcreate_config) classMcpClient ### scalekit\_client.actions.mcp.list\_configs [Section titled “scalekit\_client.actions.mcp.list\_configs”](#scalekit_clientactionsmcplist_configs) classMcpClient ### scalekit\_client.actions.mcp.update\_config [Section titled “scalekit\_client.actions.mcp.update\_config”](#scalekit_clientactionsmcpupdate_config) classMcpClient ### scalekit\_client.actions.mcp.delete\_config [Section titled “scalekit\_client.actions.mcp.delete\_config”](#scalekit_clientactionsmcpdelete_config) classMcpClient ### scalekit\_client.actions.mcp.list\_mcp\_connected\_accounts [Section titled “scalekit\_client.actions.mcp.list\_mcp\_connected\_accounts”](#scalekit_clientactionsmcplist_mcp_connected_accounts) classMcpClient ### scalekit\_client.actions.mcp.create\_session\_token [Section titled “scalekit\_client.actions.mcp.create\_session\_token”](#scalekit_clientactionsmcpcreate_session_token) classMcpClient

---
# DOCUMENT BOUNDARY
---

# Request modifiers

> AgentKit modifiers

Modifiers intercept tool calls to transform inputs or outputs, useful for validation, enrichment, or logging. 
```python
1
# actions comes from the Scalekit client (or your framework adapter)
2
actions = scalekit_client.actions
3


4
@actions.pre_modifier(tool_names=["gmail_fetch_emails"])
5
def add_default_label(tool_input):
6
    tool_input.setdefault("label", "UNREAD")
7
    return tool_input
8


9
@actions.post_modifier(tool_names=["gmail_fetch_emails"])
10
def filter_attachments(tool_output):
11
    tool_output["emails"] = [e for e in tool_output["emails"] if not e.get("has_attachment")]
12
    return tool_output
```
 | Decorator | Receives | Returns | | ------------------------------------ | -------- | --------------- | | `@actions.pre_modifier(tool_names)` | `dict` | Modified `dict` | | `@actions.post_modifier(tool_names)` | `dict` | Modified `dict` | `tool_names` accepts a string or a list of strings. Multiple modifiers for the same tool chain in registration order. ***

---
# DOCUMENT BOUNDARY
---

# Tool calling

> List raw tool schemas for custom adapters

`scalekit.tools` returns raw tool schemas for custom agent adapters. Use this when you need tool definitions for frameworks or your own executor. For connect + execute, use [Connected accounts](/agentkit/sdks/python/actions/). These methods raise on 4xx/5xx. See [Error handling](/agentkit/sdks/python/errors/). Pick a discovery method: * `list_tools` — workspace catalog * `list_scoped_tools` — tools already bound to one identifier (the list you pass to an LLM) * `search_tools` — catalog ranked by relevance to a natural-language query, with per-connection readiness `list_available_tools` is not in the Python SDK. Use `GET /api/v1/tools/available` or the Node `listAvailableTools` method. ### tools.list\_tools [Section titled “tools.list\_tools”](#toolslist_tools) classToolsClient ### tools.list\_scoped\_tools [Section titled “tools.list\_scoped\_tools”](#toolslist_scoped_tools) classToolsClient ### tools.search\_tools [Section titled “tools.search\_tools”](#toolssearch_tools) classToolsClient ### tools.execute\_tool [Section titled “tools.execute\_tool”](#toolsexecute_tool) classToolsClient Note: Need a tool Scalekit doesn’t provide? See [Build custom tools](/agentkit/tools/custom-tools/) to proxy any provider API through a connected account.

---
# DOCUMENT BOUNDARY
---

# Authorize a user

> Generate an authorization link, send it to your user, and confirm their connected account is active before your agent executes tools.

Once a connection is configured, your users need to grant your agent access to their account. This happens once per user per connection. Scalekit stores their tokens and keeps them fresh automatically. The flow is: 1. Create a connected account for the user 2. Generate an authorization link and send it to the user 3. The user completes the OAuth consent screen 4. The connected account becomes `ACTIVE`. Your agent can now execute tools. ## Create a connected account and generate a link [Section titled “Create a connected account and generate a link”](#create-a-connected-account-and-generate-a-link) * Python 
  ```python
  1
  # Create or retrieve the connected account for this user
  2
  response = actions.get_or_create_connected_account(
  3
      connection_name="github-connect",
  4
      identifier="user_123"  # your app's unique user ID
  5
  )
  6
  connected_account = response.connected_account
  7


  8
  # Generate the authorization link if the account is not yet active
  9
  if connected_account.status != "ACTIVE":
  10
      link_response = actions.get_authorization_link(
  11
          connection_name="github-connect",
  12
          identifier="user_123"
  13
      )
  14
      auth_url = link_response.link
  15
      # Redirect or send auth_url to the user
  ```
 * Node.js 
  ```typescript
  1
  import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb';
  2


  3
  // Create or retrieve the connected account for this user
  4
  const response = await actions.getOrCreateConnectedAccount({
  5
    connectionName: 'github-connect',
  6
    identifier: 'user_123',  // your app's unique user ID
  7
  });
  8


  9
  const connectedAccount = response.connectedAccount;
  10


  11
  // Generate the authorization link if the account is not yet active
  12
  if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
  13
    const linkResponse = await actions.getAuthorizationLink({
  14
      connectionName: 'github-connect',
  15
      identifier: 'user_123',
  16
    });
  17
    const authUrl = linkResponse.link;
  18
    // Redirect or send authUrl to the user
  19
  }
  ```
 ## Send the link to the user [Section titled “Send the link to the user”](#send-the-link-to-the-user) How you deliver the link depends on your application: * **Web app:** redirect the user to `auth_url` directly if they’re in an active browser session * **Email or notification:** send the link when the user isn’t actively in your app, or when connecting at their own pace is acceptable * **In-app prompt:** show a button (“Connect GitHub”) when you want to prompt connection at a specific moment in the user’s workflow Once the user opens the link and approves the OAuth consent screen, Scalekit exchanges the authorization code for tokens and marks the connected account `ACTIVE`. You do not need to handle the OAuth callback yourself. ## Check status and re-authorize [Section titled “Check status and re-authorize”](#check-status-and-re-authorize) Check the connected account status before executing tools. Tokens can expire or be revoked, so generate a new authorization link using the same flow when that happens. * Python 
  ```python
  1
  response = actions.get_or_create_connected_account(
  2
      connection_name="github-connect",
  3
      identifier="user_123"
  4
  )
  5
  connected_account = response.connected_account
  6
  # ACTIVE: ready for tool calls
  7
  # PENDING: user has not completed the OAuth flow
  8
  # EXPIRED: tokens expired, re-authorization required
  9
  # REVOKED: user revoked access from the provider
  10


  11
  if connected_account.status != "ACTIVE":
  12
      link_response = actions.get_authorization_link(
  13
          connection_name="github-connect",
  14
          identifier="user_123"
  15
      )
  16
      # Redirect or send link_response.link to the user
  ```
 * Node.js 
  ```typescript
  1
  import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb';
  2


  3
  const response = await actions.getOrCreateConnectedAccount({
  4
    connectionName: 'github-connect',
  5
    identifier: 'user_123',
  6
  });
  7


  8
  const connectedAccount = response.connectedAccount;
  9
  // ACTIVE: ready for tool calls
  10
  // PENDING: user has not completed the OAuth flow
  11
  // EXPIRED: tokens expired, re-authorization required
  12
  // REVOKED: user revoked access from the provider
  13


  14
  if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
  15
    const linkResponse = await actions.getAuthorizationLink({
  16
      connectionName: 'github-connect',
  17
      identifier: 'user_123',
  18
    });
  19
    // Redirect or send linkResponse.link to the user
  20
  }
  ```

---
# DOCUMENT BOUNDARY
---

# Pre and Post Processors

> Learn how to create pre and post processor workflows that are run before or after tool execution with Agent Auth.

Custom pre and post processors are a way to create custom workflows that are run before or after tool execution with Agent Auth. They are useful for: * Validating and transforming input data * Processing and Formatting output data * Adding additional context to the tool execution ## Usage [Section titled “Usage”](#usage)

---
# DOCUMENT BOUNDARY
---

# Custom tools

> Build tools that Scalekit does not provide out of the box by proxying provider API calls through connected accounts.

When you need a connector tool that Scalekit doesn’t offer as a pre-built tool, use **API Proxy mode**. You define the tool contract and call the provider endpoint through `actions.request`. Scalekit injects the user’s credentials from their connected account; your agent never handles raw tokens. | Option | Best for | Who defines tool schema | | ------------------------ | --------------------------------- | ----------------------- | | Scalekit optimized tools | Common connector tools | Scalekit | | Custom tools (API Proxy) | Unsupported or app-specific tools | Your application | This page assumes the user has an `ACTIVE` connected account. If not, see [Authorize a user](/agentkit/tools/authorize/). ## Find the right endpoint [Section titled “Find the right endpoint”](#find-the-right-endpoint) The `path` you pass to `actions.request` is forwarded directly to the provider’s API; Scalekit only adds authentication headers. Look up the provider’s API reference to get the correct path, method, and request shape. | Connector | API reference | | ---------- | ------------------------------------------------------------------------------------------------ | | Gmail | [Google Gmail API](https://developers.google.com/gmail/api/reference/rest) | | Slack | [Slack API methods](https://api.slack.com/methods) | | GitHub | [GitHub REST API](https://docs.github.com/en/rest) | | Salesforce | [Salesforce REST API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/) | | HubSpot | [HubSpot API](https://developers.hubspot.com/docs/api/overview) | ## Define your tool contract [Section titled “Define your tool contract”](#define-your-tool-contract) Design the tool around your agent’s intent, not the provider’s API surface. For example, to list Gmail filters: * **Tool name:** `gmail_list_filters` (describes the action, not the endpoint) * **Input:** `identifier` (your app’s user ID) * **Output:** `{ filters: [...], count: N }` (structured, not the raw Gmail response) Keep schemas focused on what the model needs. Strip provider-specific noise before returning data. ## Proxy the API call [Section titled “Proxy the API call”](#proxy-the-api-call) Use `actions.request` to call any provider endpoint. Scalekit handles credential injection. **GET requests:** pass query parameters as a dict: * Python 
  ```python
  1
  def gmail_list_filters(identifier: str):
  2
      response = actions.request(
  3
          connection_name="gmail",
  4
          identifier=identifier,
  5
          method="GET",
  6
          path="/gmail/v1/users/me/settings/filters",
  7
      )
  8
      data = response.json()
  9
      return {"filters": data.get("filter", []), "count": len(data.get("filter", []))}
  10


  11
  def gmail_list_unread(identifier: str, max_results: int = 10):
  12
      response = actions.request(
  13
          connection_name="gmail",
  14
          identifier=identifier,
  15
          method="GET",
  16
          path="/gmail/v1/users/me/messages",
  17
          query_params={"q": "is:unread", "maxResults": max_results},
  18
      )
  19
      return {"messages": response.json().get("messages", [])}
  ```
 * Node.js 
  ```typescript
  1
  async function gmailListFilters(identifier: string) {
  2
    const response = await scalekit.actions.request({
  3
      connectionName: 'gmail',
  4
      identifier,
  5
      method: 'GET',
  6
      path: '/gmail/v1/users/me/settings/filters',
  7
    });
  8
    const filters = response.data?.filter ?? [];
  9
    return { filters, count: filters.length };
  10
  }
  11


  12
  async function gmailListUnread(identifier: string, maxResults = 10) {
  13
    const response = await scalekit.actions.request({
  14
      connectionName: 'gmail',
  15
      identifier,
  16
      method: 'GET',
  17
      path: '/gmail/v1/users/me/messages',
  18
      queryParams: { q: 'is:unread', maxResults },
  19
    });
  20
    return { messages: response.data?.messages ?? [] };
  21
  }
  ```
 **POST requests:** pass a body for write operations: * Python 
  ```python
  1
  def slack_send_message(identifier: str, channel: str, text: str):
  2
      response = actions.request(
  3
          connection_name="slack",
  4
          identifier=identifier,
  5
          method="POST",
  6
          path="/api/chat.postMessage",
  7
          body={"channel": channel, "text": text},
  8
      )
  9
      data = response.json()
  10
      if not data.get("ok"):
  11
          raise ValueError(f"Slack error: {data.get('error')}")
  12
      return {"ts": data.get("ts"), "channel": data.get("channel")}
  ```
 * Node.js 
  ```typescript
  1
  async function slackSendMessage(identifier: string, channel: string, text: string) {
  2
    const response = await scalekit.actions.request({
  3
      connectionName: 'slack',
  4
      identifier,
  5
      method: 'POST',
  6
      path: '/api/chat.postMessage',
  7
      body: { channel, text },
  8
    });
  9
    if (!response.data?.ok) throw new Error(`Slack error: ${response.data?.error}`);
  10
    return { ts: response.data.ts, channel: response.data.channel };
  11
  }
  ```
 ## Check authorization before proxy calls [Section titled “Check authorization before proxy calls”](#check-authorization-before-proxy-calls) Verify the connected account is `ACTIVE` before making a proxy call and handle provider errors explicitly: * Python 
  ```python
  1
  account = actions.get_or_create_connected_account(
  2
      connection_name="gmail",
  3
      identifier=identifier,
  4
  ).connected_account
  5


  6
  if account.status != "ACTIVE":
  7
      raise ValueError("Connected account is not ACTIVE. Re-authorize the user.")
  ```
 * Node.js 
  ```typescript
  1
  import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb';
  2


  3
  const account = (await scalekit.actions.getOrCreateConnectedAccount({
  4
    connectionName: 'gmail',
  5
    identifier,
  6
  })).connectedAccount;
  7


  8
  if (account?.status !== ConnectorStatus.ACTIVE) {
  9
    throw new Error('Connected account is not ACTIVE. Re-authorize the user.');
  10
  }
  ```
 ## Best practices [Section titled “Best practices”](#best-practices) * Expose only the fields your model needs; keep schemas small * Validate inputs server-side; never trust model-generated parameters * Use predictable JSON keys; return stable output across calls * Map provider errors to clear tool errors; don’t leak raw provider payloads to prompts

---
# DOCUMENT BOUNDARY
---

# Proxy Tools

> Learn how to make direct API calls to providers using Agent Auth's proxy tools.

Custom tool definitions allow you to create specialized tools tailored to your specific business needs. You can combine multiple provider tools, add custom logic, and create reusable workflows that go beyond standard tool functionality. ## What are custom tools? [Section titled “What are custom tools?”](#what-are-custom-tools) Custom tools are user-defined functions that: * **Extend existing tools**: Build on top of standard provider tools * **Combine multiple operations**: Create workflows that use multiple tools * **Add business logic**: Include custom validation, processing, and formatting * **Create reusable patterns**: Standardize common operations across your team * **Integrate with external systems**: Connect to your own APIs and services ## Custom tool structure [Section titled “Custom tool structure”](#custom-tool-structure) Every custom tool follows a standardized structure: 
```javascript
1
{
2
  name: 'custom_tool_name',
3
  display_name: 'Custom Tool Display Name',
4
  description: 'Description of what the tool does',
5
  category: 'custom',
6
  provider: 'custom',
7
  input_schema: {
8
    type: 'object',
9
    properties: {
10
      // Define input parameters
11
    },
12
    required: ['required_param']
13
  },
14
  output_schema: {
15
    type: 'object',
16
    properties: {
17
      // Define output format
18
    }
19
  },
20
  implementation: async (parameters, context) => {
21
    // Custom tool logic
22
    return result;
23
  }
24
}
```
 ## Creating custom tools [Section titled “Creating custom tools”](#creating-custom-tools) ### Basic custom tool [Section titled “Basic custom tool”](#basic-custom-tool) Here’s a simple custom tool that sends a welcome email: 
```javascript
1
const sendWelcomeEmail = {
2
  name: 'send_welcome_email',
3
  display_name: 'Send Welcome Email',
4
  description: 'Send a personalized welcome email to new users',
5
  category: 'communication',
6
  provider: 'custom',
7
  input_schema: {
8
    type: 'object',
9
    properties: {
10
      user_name: {
11
        type: 'string',
12
        description: 'Name of the new user'
13
      },
14
      user_email: {
15
        type: 'string',
16
        format: 'email',
17
        description: 'Email address of the new user'
18
      },
19
      company_name: {
20
        type: 'string',
21
        description: 'Name of the company'
22
      }
23
    },
24
    required: ['user_name', 'user_email', 'company_name']
25
  },
26
  output_schema: {
27
    type: 'object',
28
    properties: {
29
      message_id: {
30
        type: 'string',
31
        description: 'ID of the sent email'
32
      },
33
      status: {
34
        type: 'string',
35
        enum: ['sent', 'failed'],
36
        description: 'Status of the email'
37
      }
38
    }
39
  },
40
  implementation: async (parameters, context) => {
41
    const { user_name, user_email, company_name } = parameters;
42


43
    // Generate personalized email content
44
    const emailBody = `
45
      Welcome to ${company_name}, ${user_name}!
46


47
      We're excited to have you join our team. Here are some next steps:
48


49
      1. Complete your profile setup
50
      2. Join our Slack workspace
51
      3. Schedule a meeting with your manager
52


53
      If you have any questions, don't hesitate to reach out!
54


55
      Best regards,
56
      The ${company_name} Team
57
    `;
58


59
    // Send email using standard email tool
60
    const result = await context.tools.execute({
61
      tool: 'send_email',
62
      parameters: {
63
        to: [user_email],
64
        subject: `Welcome to ${company_name}!`,
65
        body: emailBody
66
      }
67
    });
68


69
    return {
70
      message_id: result.message_id,
71
      status: result.status === 'sent' ? 'sent' : 'failed'
72
    };
73
  }
74
};
```
 ### Multi-step workflow tool [Section titled “Multi-step workflow tool”](#multi-step-workflow-tool) Create a tool that combines multiple operations: 
```javascript
1
const createProjectWorkflow = {
2
  name: 'create_project_workflow',
3
  display_name: 'Create Project Workflow',
4
  description: 'Create a complete project setup with Jira project, Slack channel, and team notifications',
5
  category: 'project_management',
6
  provider: 'custom',
7
  input_schema: {
8
    type: 'object',
9
    properties: {
10
      project_name: {
11
        type: 'string',
12
        description: 'Name of the project'
13
      },
14
      project_key: {
15
        type: 'string',
16
        description: 'Project key for Jira'
17
      },
18
      team_members: {
19
        type: 'array',
20
        items: { type: 'string', format: 'email' },
21
        description: 'Team member email addresses'
22
      },
23
      project_description: {
24
        type: 'string',
25
        description: 'Project description'
26
      }
27
    },
28
    required: ['project_name', 'project_key', 'team_members']
29
  },
30
  output_schema: {
31
    type: 'object',
32
    properties: {
33
      jira_project_id: { type: 'string' },
34
      slack_channel_id: { type: 'string' },
35
      notifications_sent: { type: 'number' }
36
    }
37
  },
38
  implementation: async (parameters, context) => {
39
    const { project_name, project_key, team_members, project_description } = parameters;
40


41
    try {
42
      // Step 1: Create Jira project
43
      const jiraProject = await context.tools.execute({
44
        tool: 'create_jira_project',
45
        parameters: {
46
          key: project_key,
47
          name: project_name,
48
          description: project_description,
49
          project_type: 'software'
50
        }
51
      });
52


53
      // Step 2: Create Slack channel
54
      const slackChannel = await context.tools.execute({
55
        tool: 'create_channel',
56
        parameters: {
57
          name: `${project_key.toLowerCase()}-team`,
58
          topic: `Discussion for ${project_name}`,
59
          is_private: false
60
        }
61
      });
62


63
      // Step 3: Send notifications to team members
64
      let notificationCount = 0;
65
      for (const member of team_members) {
66
        try {
67
          await context.tools.execute({
68
            tool: 'send_email',
69
            parameters: {
70
              to: [member],
71
              subject: `New Project: ${project_name}`,
72
              body: `
73
                You've been added to the new project "${project_name}".
74


75
                Jira Project: ${jiraProject.project_url}
76
                Slack Channel: #${slackChannel.channel_name}
77


78
                Please join the Slack channel to start collaborating!
79
              `
80
            }
81
          });
82
          notificationCount++;
83
        } catch (error) {
84
          console.error(`Failed to send notification to ${member}:`, error);
85
        }
86
      }
87


88
      // Step 4: Post welcome message to Slack channel
89
      await context.tools.execute({
90
        tool: 'send_message',
91
        parameters: {
92
          channel: `#${slackChannel.channel_name}`,
93
          text: `<� Welcome to ${project_name}! This channel is for project discussion and updates.`
94
        }
95
      });
96


97
      return {
98
        jira_project_id: jiraProject.project_id,
99
        slack_channel_id: slackChannel.channel_id,
100
        notifications_sent: notificationCount
101
      };
102


103
    } catch (error) {
104
      throw new Error(`Project creation failed: ${error.message}`);
105
    }
106
  }
107
};
```
 ### Data processing tool [Section titled “Data processing tool”](#data-processing-tool) Create a tool that processes and analyzes data: 
```javascript
1
const generateTeamReport = {
2
  name: 'generate_team_report',
3
  display_name: 'Generate Team Report',
4
  description: 'Generate a comprehensive team performance report from multiple sources',
5
  category: 'analytics',
6
  provider: 'custom',
7
  input_schema: {
8
    type: 'object',
9
    properties: {
10
      team_members: {
11
        type: 'array',
12
        items: { type: 'string', format: 'email' },
13
        description: 'Team member email addresses'
14
      },
15
      start_date: {
16
        type: 'string',
17
        format: 'date',
18
        description: 'Report start date'
19
      },
20
      end_date: {
21
        type: 'string',
22
        format: 'date',
23
        description: 'Report end date'
24
      },
25
      include_calendar: {
26
        type: 'boolean',
27
        default: true,
28
        description: 'Include calendar analysis'
29
      }
30
    },
31
    required: ['team_members', 'start_date', 'end_date']
32
  },
33
  output_schema: {
34
    type: 'object',
35
    properties: {
36
      report_url: { type: 'string' },
37
      summary: { type: 'object' },
38
      sent_to: { type: 'array', items: { type: 'string' } }
39
    }
40
  },
41
  implementation: async (parameters, context) => {
42
    const { team_members, start_date, end_date, include_calendar } = parameters;
43


44
    // Fetch Jira issues assigned to team members
45
    const jiraIssues = await context.tools.execute({
46
      tool: 'fetch_issues',
47
      parameters: {
48
        jql: `assignee in (${team_members.join(',')}) AND created >= ${start_date} AND created <= ${end_date}`,
49
        fields: ['summary', 'status', 'assignee', 'created', 'resolved']
50
      }
51
    });
52


53
    // Fetch calendar events if requested
54
    let calendarData = null;
55
    if (include_calendar) {
56
      calendarData = await context.tools.execute({
57
        tool: 'fetch_events',
58
        parameters: {
59
          start_date: start_date,
60
          end_date: end_date,
61
          attendees: team_members
62
        }
63
      });
64
    }
65


66
    // Process and analyze data
67
    const report = {
68
      period: { start_date, end_date },
69
      team_size: team_members.length,
70
      issues: {
71
        total: jiraIssues.issues.length,
72
        completed: jiraIssues.issues.filter(i => i.status === 'Done').length,
73
        in_progress: jiraIssues.issues.filter(i => i.status === 'In Progress').length
74
      },
75
      meetings: calendarData ? {
76
        total: calendarData.events.length,
77
        hours: calendarData.events.reduce((acc, event) => acc + event.duration, 0)
78
      } : null
79
    };
80


81
    // Generate HTML report
82
    const htmlReport = `
83
      
84
        Team Report - ${start_date} to ${end_date}
85
        
86
          

Team Performance Report

87

Summary

88

Team Size: ${report.team_size}

89

Total Issues: ${report.issues.total}

90

Completed Issues: ${report.issues.completed}

91

In Progress: ${report.issues.in_progress}

92 ${report.meetings ? `

Total Meetings: ${report.meetings.total}

` : ''} 93 94 95 `; 96 97 // Send report via email 98 const emailResults = await Promise.all( 99 team_members.map(member => 100 context.tools.execute({ 101 tool: 'send_email', 102 parameters: { 103 to: [member], 104 subject: `Team Report - ${start_date} to ${end_date}`, 105 html_body: htmlReport 106 } 107 }) 108 ) 109 ); 110 111 return { 112 report_url: 'Generated and sent via email', 113 summary: report, 114 sent_to: team_members.filter((_, index) => emailResults[index].status === 'sent') 115 }; 116 } 117 }; ``` ## Registering custom tools [Section titled “Registering custom tools”](#registering-custom-tools) ### Using the API [Section titled “Using the API”](#using-the-api) Register your custom tools with Agent Auth: * JavaScript ```javascript 1 // Register a custom tool 2 const registeredTool = await agentConnect.tools.register({ 3 ...sendWelcomeEmail, 4 organization_id: 'your_org_id' 5 }); 6 7 console.log('Tool registered:', registeredTool.id); ``` * Python ```python 1 # Register a custom tool 2 registered_tool = agent_connect.tools.register( 3 **send_welcome_email, 4 organization_id='your_org_id' 5 ) 6 7 print(f'Tool registered: {registered_tool.id}') ``` * cURL ```bash 1 curl -X POST "${SCALEKIT_BASE_URL}/v1/connect/tools/custom" \ 2 -H "Authorization: Bearer ${SCALEKIT_CLIENT_SECRET}" \ 3 -H "Content-Type: application/json" \ 4 -d '{ 5 "name": "send_welcome_email", 6 "display_name": "Send Welcome Email", 7 "description": "Send a personalized welcome email to new users", 8 "category": "communication", 9 "provider": "custom", 10 "input_schema": {...}, 11 "output_schema": {...}, 12 "implementation": "async (parameters, context) => {...}" 13 }' ``` ### Using the dashboard [Section titled “Using the dashboard”](#using-the-dashboard) 1. In the [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Tools** 2. Click **Create Custom Tool** 3. Fill in the tool definition form 4. Test the tool with sample parameters 5. Save and activate the tool ## Tool context and utilities [Section titled “Tool context and utilities”](#tool-context-and-utilities) The `context` object provides access to: ### Standard tools [Section titled “Standard tools”](#standard-tools) Execute any standard Agent Auth tool: ```javascript 1 // Execute standard tools 2 const result = await context.tools.execute({ 3 tool: 'send_email', 4 parameters: { ... } 5 }); 6 7 // Execute with specific connected account 8 const result = await context.tools.execute({ 9 connected_account_id: 'specific_account', 10 tool: 'send_email', 11 parameters: { ... } 12 }); ``` ### Connected accounts [Section titled “Connected accounts”](#connected-accounts) Access connected account information: ```javascript 1 // Get connected account details 2 const account = await context.accounts.get(accountId); 3 4 // List accounts for a user 5 const accounts = await context.accounts.list({ 6 identifier: 'user_123', 7 provider: 'gmail' 8 }); ``` ### Utilities [Section titled “Utilities”](#utilities) Access utility functions: ```javascript 1 // Generate unique IDs 2 const id = context.utils.generateId(); 3 4 // Format dates 5 const formatted = context.utils.formatDate(date, 'YYYY-MM-DD'); 6 7 // Validate email 8 const isValid = context.utils.isValidEmail(email); 9 10 // HTTP requests 11 const response = await context.utils.httpRequest({ 12 url: 'https://api.example.com/data', 13 method: 'GET', 14 headers: { 'Authorization': 'Bearer token' } 15 }); ``` ### Error handling [Section titled “Error handling”](#error-handling) Throw structured errors: ```javascript 1 // Throw validation error 2 throw new context.errors.ValidationError('Invalid email format'); 3 4 // Throw business logic error 5 throw new context.errors.BusinessLogicError('User not found'); 6 7 // Throw external API error 8 throw new context.errors.ExternalAPIError('GitHub API returned 500'); ``` ## Testing custom tools [Section titled “Testing custom tools”](#testing-custom-tools) ### Unit testing [Section titled “Unit testing”](#unit-testing) Test custom tools in isolation: ```javascript 1 // Mock context for testing 2 const mockContext = { 3 tools: { 4 execute: jest.fn().mockResolvedValue({ 5 message_id: 'test_msg_123', 6 status: 'sent' 7 }) 8 }, 9 utils: { 10 generateId: () => 'test_id_123', 11 formatDate: (date, format) => '2024-01-15' 12 } 13 }; 14 15 // Test custom tool 16 const result = await sendWelcomeEmail.implementation({ 17 user_name: 'John Doe', 18 user_email: 'john@example.com', 19 company_name: 'Acme Corp' 20 }, mockContext); 21 22 expect(result.status).toBe('sent'); 23 expect(mockContext.tools.execute).toHaveBeenCalledWith({ 24 tool: 'send_email', 25 parameters: expect.objectContaining({ 26 to: ['john@example.com'], 27 subject: 'Welcome to Acme Corp!' 28 }) 29 }); ``` ### Integration testing [Section titled “Integration testing”](#integration-testing) Test with real Agent Auth: ```javascript 1 // Test custom tool with real connections 2 const testResult = await agentConnect.tools.execute({ 3 connected_account_id: 'test_gmail_account', 4 tool: 'send_welcome_email', 5 parameters: { 6 user_name: 'Test User', 7 user_email: 'test@example.com', 8 company_name: 'Test Company' 9 } 10 }); 11 12 console.log('Test result:', testResult); ``` ## Best practices [Section titled “Best practices”](#best-practices) ### Tool design [Section titled “Tool design”](#tool-design) * **Single responsibility**: Each tool should have a clear, single purpose * **Consistent naming**: Use descriptive, consistent naming conventions * **Clear documentation**: Provide detailed descriptions and examples * **Error handling**: Implement comprehensive error handling * **Input validation**: Validate all input parameters ### Performance optimization [Section titled “Performance optimization”](#performance-optimization) * **Parallel execution**: Use Promise.all() for independent operations * **Caching**: Cache frequently accessed data * **Batch operations**: Group similar operations together * **Timeout handling**: Set appropriate timeouts for external calls ### Security considerations [Section titled “Security considerations”](#security-considerations) * **Input sanitization**: Sanitize all user inputs * **Permission checks**: Verify user permissions before execution * **Sensitive data**: Handle sensitive data securely * **Rate limiting**: Implement rate limiting for resource-intensive operations ## Custom tool examples [Section titled “Custom tool examples”](#custom-tool-examples) ### Slack notification tool [Section titled “Slack notification tool”](#slack-notification-tool) ```javascript 1 const sendSlackNotification = { 2 name: 'send_slack_notification', 3 display_name: 'Send Slack Notification', 4 description: 'Send formatted notifications to Slack with optional mentions', 5 category: 'communication', 6 provider: 'custom', 7 input_schema: { 8 type: 'object', 9 properties: { 10 channel: { type: 'string' }, 11 message: { type: 'string' }, 12 severity: { type: 'string', enum: ['info', 'warning', 'error'] }, 13 mentions: { type: 'array', items: { type: 'string' } } 14 }, 15 required: ['channel', 'message'] 16 }, 17 output_schema: { 18 type: 'object', 19 properties: { 20 message_ts: { type: 'string' }, 21 permalink: { type: 'string' } 22 } 23 }, 24 implementation: async (parameters, context) => { 25 const { channel, message, severity = 'info', mentions = [] } = parameters; 26 27 const colors = { 28 info: 'good', 29 warning: 'warning', 30 error: 'danger' 31 }; 32 33 const mentionText = mentions.length > 0 ? 34 `${mentions.map(m => `<@${m}>`).join(' ')} ` : ''; 35 36 return await context.tools.execute({ 37 tool: 'send_message', 38 parameters: { 39 channel, 40 text: `${mentionText}${message}`, 41 attachments: [ 42 { 43 color: colors[severity], 44 text: message, 45 ts: Math.floor(Date.now() / 1000) 46 } 47 ] 48 } 49 }); 50 } 51 }; ``` ### Calendar scheduling tool [Section titled “Calendar scheduling tool”](#calendar-scheduling-tool) ```javascript 1 const scheduleTeamMeeting = { 2 name: 'schedule_team_meeting', 3 display_name: 'Schedule Team Meeting', 4 description: 'Find available time slots and schedule team meetings', 5 category: 'scheduling', 6 provider: 'custom', 7 input_schema: { 8 type: 'object', 9 properties: { 10 attendees: { type: 'array', items: { type: 'string' } }, 11 duration: { type: 'number', minimum: 15 }, 12 preferred_times: { type: 'array', items: { type: 'string' } }, 13 meeting_title: { type: 'string' }, 14 meeting_description: { type: 'string' } 15 }, 16 required: ['attendees', 'duration', 'meeting_title'] 17 }, 18 output_schema: { 19 type: 'object', 20 properties: { 21 event_id: { type: 'string' }, 22 scheduled_time: { type: 'string' }, 23 attendees_notified: { type: 'number' } 24 } 25 }, 26 implementation: async (parameters, context) => { 27 const { attendees, duration, preferred_times, meeting_title, meeting_description } = parameters; 28 29 // Find available time slots 30 const availableSlots = await context.tools.execute({ 31 tool: 'find_available_slots', 32 parameters: { 33 attendees, 34 duration, 35 preferred_times: preferred_times || [] 36 } 37 }); 38 39 if (availableSlots.length === 0) { 40 throw new context.errors.BusinessLogicError('No available time slots found'); 41 } 42 43 // Schedule the meeting at the first available slot 44 const selectedSlot = availableSlots[0]; 45 const event = await context.tools.execute({ 46 tool: 'create_event', 47 parameters: { 48 title: meeting_title, 49 description: meeting_description, 50 start_time: selectedSlot.start_time, 51 end_time: selectedSlot.end_time, 52 attendees 53 } 54 }); 55 56 return { 57 event_id: event.event_id, 58 scheduled_time: selectedSlot.start_time, 59 attendees_notified: attendees.length 60 }; 61 } 62 }; ``` ## Versioning and deployment [Section titled “Versioning and deployment”](#versioning-and-deployment) ### Version management [Section titled “Version management”](#version-management) Version your custom tools for backward compatibility: ```javascript 1 const toolV2 = { 2 ...originalTool, 3 version: '2.0.0', 4 // Updated implementation 5 }; 6 7 // Deploy new version 8 await agentConnect.tools.register(toolV2); 9 10 // Deprecate old version 11 await agentConnect.tools.deprecate(originalTool.name, '1.0.0'); ``` ### Deployment strategies [Section titled “Deployment strategies”](#deployment-strategies) * **Blue-green deployment**: Deploy new version alongside old version * **Canary deployment**: Gradually roll out to subset of users * **Feature flags**: Use feature flags to control tool availability * **Rollback strategy**: Plan for quick rollback if issues arise Custom tools unlock the full potential of Agent Auth by allowing you to create specialized workflows that perfectly match your business needs. With proper design, testing, and deployment practices, you can build powerful tools that enhance your team’s productivity and streamline complex operations. --- # DOCUMENT BOUNDARY --- # Scalekit optimized built-in tools > Call Scalekit's pre-built tools across 200+ connectors. Each tool returns structured, LLM-ready output with no endpoint URLs, auth headers, or parsing needed. Scalekit ships pre-built tools for every connector in the catalog: GitHub, Gmail, Slack, Salesforce, Notion, Linear, HubSpot, and more. Each tool has an LLM-ready schema and returns structured output. Your agent passes inputs; Scalekit injects the user’s credentials and handles the API call. This page assumes you have an `ACTIVE` connected account for the user. If not, see [Authorize a user](/agentkit/tools/authorize/). ## Get available tools for a user [Section titled “Get available tools for a user”](#get-available-tools-for-a-user) Use `list_scoped_tools` / `listScopedTools` to get the tools this specific user is authorized to call. **This is the list you pass to your LLM.** The other two fetch methods are different: * `list_tools` / `listTools` — workspace catalog, not bound to one user * `listAvailableTools` — tools you can make available for an identifier (Node SDK and `GET /api/v1/tools/available`; not in the Python SDK) See [Node tool calling](/agentkit/sdks/node/tools/) and [Python tool calling](/agentkit/sdks/python/tools/) for when to use each method. * Python ```python 1 from google.protobuf.json_format import MessageToDict 2 3 scoped_response, _ = actions.tools.list_scoped_tools( 4 identifier="user_123", 5 filter={"connection_names": ["github-connect"]}, # optional; omit for all connectors 6 page_size=100, # fetch beyond the default page 7 ) 8 for scoped_tool in scoped_response.tools: 9 definition = MessageToDict(scoped_tool.tool).get("definition", {}) 10 print(definition.get("name")) 11 print(definition.get("input_schema")) # JSON Schema; pass directly to your LLM ``` * Node.js ```typescript 1 const { tools } = await scalekit.tools.listScopedTools('user_123', { 2 filter: { connectionNames: ['github-connect'] }, // use filter: {} to list every connector 3 pageSize: 100, // fetch beyond the default page 4 }); 5 for (const tool of tools) { 6 const { name, input_schema } = tool.tool.definition; 7 console.log(name, input_schema); // JSON Schema; pass directly to your LLM 8 } ``` To explore tools interactively, use the playground at [**Scalekit Dashboard**](https://app.scalekit.com) **> AgentKit > Playground**. ## Execute a tool [Section titled “Execute a tool”](#execute-a-tool) Use `execute_tool` / `executeTool` to run a named tool for a specific user. Scalekit identifies the connected account with: * User identifier (`identifier`) + Connection name as shown in the Scalekit Dashboard (`connection_name`), or * Connected Account ID (`connected_account_id`) — autogenerated by Scalekit and visible in the Scalekit Dashboard - Python ```python 1 # connected account is selected using the user identifier and the connection name 2 result = actions.execute_tool( 3 tool_name="github_user_repos_list", 4 identifier="user_123", 5 connection_name="github-connect", 6 tool_input={"per_page": 5, "sort": "updated"}, 7 ) 8 print(result.data) 9 10 # alternatively, use the connected account ID 11 # result = actions.execute_tool( 12 # tool_name="github_user_repos_list", 13 # connected_account_id="ca_xxxxxx", 14 # tool_input={"per_page": 5, "sort": "updated"}, 15 # ) ``` - Node.js ```typescript 1 // connected account is selected using the user identifier and the connector 2 const result = await scalekit.actions.executeTool({ 3 toolName: 'github_user_repos_list', 4 identifier: 'user_123', 5 connector: 'github-connect', 6 toolInput: { per_page: 5, sort: 'updated' }, 7 }); 8 console.log(result.data); 9 10 // alternatively, use the connected account ID 11 // const result = await scalekit.actions.executeTool({ 12 // toolName: 'github_user_repos_list', 13 // connectedAccountId: 'ca_xxxxxx', 14 // toolInput: { per_page: 5, sort: 'updated' }, 15 // }); ``` ## Understand tool response shape [Section titled “Understand tool response shape”](#understand-tool-response-shape) `execute_tool` / `executeTool` returns a **wrapper object**, not the provider payload directly. Tool output lives under `response.data` (Python) or `result.data` (Node.js). Keys inside `data` depend on the tool you called. When you integrate a new tool, log the full wrapper once, then read fields from `data`: * Python List Google Calendar events (Python) ```python 1 response = actions.execute_tool( 2 tool_name="googlecalendar_list_events", 3 identifier="user_123", 4 connection_name="googlecalendar", 5 tool_input={"max_results": 10}, 6 ) 7 8 # Security: Log only in development; production logs may expose user data. 9 print(response.data) 10 11 events = response.data.get("events", []) 12 next_page_token = response.data.get("next_page_token") 13 print(f"Found {len(events)} events") ``` * Node.js List Google Calendar events (Node.js) ```typescript 1 const result = await scalekit.actions.executeTool({ 2 toolName: 'googlecalendar_list_events', 3 identifier: 'user_123', 4 connector: 'googlecalendar', 5 toolInput: { max_results: 10 }, 6 }); 7 8 // Security: Log only in development; production logs may expose user data. 9 console.log(result.data); 10 11 const events = (result.data as { events?: unknown[] }).events ?? []; 12 const nextPageToken = (result.data as { next_page_token?: string }).next_page_token; 13 console.log(`Found ${events.length} events`); ``` Do not treat the wrapper as the tool payload A common integration mistake is parsing `response` as if it were a flat list of events. Always read `response.data` first, then extract tool-specific keys such as `events` and `next_page_token`. ## Wire into your LLM [Section titled “Wire into your LLM”](#wire-into-your-llm) The full agent loop: fetch scoped tools → pass to LLM → execute tool calls → feed results back. * Python ```python 1 import anthropic 2 from google.protobuf.json_format import MessageToDict 3 4 client = anthropic.Anthropic() 5 6 # 1. Fetch tools scoped to this user 7 scoped_response, _ = actions.tools.list_scoped_tools( 8 identifier="user_123", 9 filter={"connection_names": ["github-connect"]}, 10 page_size=100, # fetch beyond the default page so no connector tools are missed 11 ) 12 llm_tools = [ 13 { 14 "name": MessageToDict(t.tool).get("definition", {}).get("name"), 15 "description": MessageToDict(t.tool).get("definition", {}).get("description"), 16 "input_schema": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}), 17 } 18 for t in scoped_response.tools 19 ] 20 21 # 2. Send to LLM 22 messages = [{"role": "user", "content": "Summarize my 5 most recently updated repositories"}] 23 response = client.messages.create( 24 model="claude-sonnet-4-6", 25 max_tokens=1024, 26 tools=llm_tools, 27 messages=messages, 28 ) 29 30 # 3. Execute tool calls and feed results back 31 for block in response.content: 32 if block.type == "tool_use": 33 tool_result = actions.execute_tool( 34 tool_name=block.name, 35 identifier="user_123", 36 tool_input=block.input, 37 ) 38 messages.append({"role": "assistant", "content": response.content}) 39 messages.append({ 40 "role": "user", 41 "content": [{"type": "tool_result", "tool_use_id": block.id, "content": str(tool_result.data)}], 42 }) ``` * Node.js ```typescript 1 import Anthropic from '@anthropic-ai/sdk'; 2 3 const anthropic = new Anthropic(); 4 5 // 1. Fetch tools scoped to this user 6 const { tools } = await scalekit.tools.listScopedTools('user_123', { 7 filter: { connectionNames: ['github-connect'] }, 8 pageSize: 100, // fetch beyond the default page so no connector tools are missed 9 }); 10 const llmTools = tools.map((t) => ({ 11 name: t.tool.definition.name, 12 description: t.tool.definition.description, 13 input_schema: t.tool.definition.input_schema, 14 })); 15 16 // 2. Send to LLM 17 const messages: Anthropic.MessageParam[] = [ 18 { role: 'user', content: 'Summarize my 5 most recently updated repositories' }, 19 ]; 20 const response = await anthropic.messages.create({ 21 model: 'claude-sonnet-4-6', 22 max_tokens: 1024, 23 tools: llmTools, 24 messages, 25 }); 26 27 // 3. Execute tool calls and feed results back 28 for (const block of response.content) { 29 if (block.type === 'tool_use') { 30 const toolResult = await scalekit.actions.executeTool({ 31 toolName: block.name, 32 identifier: 'user_123', 33 toolInput: block.input as Record, 34 }); 35 messages.push({ role: 'assistant', content: response.content }); 36 messages.push({ 37 role: 'user', 38 content: [{ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(toolResult.data) }], 39 }); 40 } 41 } ``` ## Use a framework adapter [Section titled “Use a framework adapter”](#use-a-framework-adapter) For LangChain and Google ADK, Scalekit returns native tool objects in Python with no schema reshaping needed. * LangChain ```python 1 from langchain_openai import ChatOpenAI 2 from langchain.agents import create_agent 3 4 tools = actions.langchain.get_tools( 5 identifier="user_123", 6 connection_names=["github-connect"], 7 page_size=100, # avoid missing tools when a connector has more than the default page 8 ) 9 llm = ChatOpenAI(model="claude-sonnet-4-6") 10 agent = create_agent(model=llm, tools=tools, system_prompt="You are a helpful assistant.") 11 result = agent.invoke({"messages": [{"role": "user", "content": "List my 5 most recently updated repositories"}]}) ``` * Google ADK ```python 1 from google.adk.agents import Agent 2 from google.adk.models.lite_llm import LiteLlm 3 4 github_tools = actions.google.get_tools( 5 identifier="user_123", 6 connection_names=["github-connect"], 7 page_size=100, # avoid missing tools when a connector has more than the default page 8 ) 9 agent = Agent( 10 name="github_assistant", 11 model=LiteLlm(model="claude-sonnet-4-6"), 12 tools=github_tools, 13 ) ``` * Node.js (Vercel AI SDK) ```typescript 1 import { generateText, jsonSchema, tool } from 'ai'; 2 3 const { tools: scopedTools } = await scalekit.tools.listScopedTools('user_123', { 4 filter: { connectionNames: ['github-connect'] }, 5 pageSize: 100, // fetch beyond the default page so no connector tools are missed 6 }); 7 const tools = Object.fromEntries( 8 scopedTools.map((t) => [ 9 t.tool.definition.name, 10 tool({ 11 description: t.tool.definition.description, 12 parameters: jsonSchema(t.tool.definition.input_schema ?? { type: 'object', properties: {} }), 13 execute: async (args) => { 14 const result = await scalekit.actions.executeTool({ 15 toolName: t.tool.definition.name, 16 toolInput: args, 17 identifier: 'user_123', 18 }); 19 return result.data; 20 }, 21 }), 22 ]), 23 ); ``` ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If you need an endpoint not covered by optimized tools, see [Custom tools](/agentkit/tools/custom-tools/). --- # DOCUMENT BOUNDARY --- # Verify user identity > Confirm that the user who completed the OAuth consent is the same user your app intended to connect. User verification applies to OAuth-based connectors only. For API key, basic auth, and key pair connectors, the user provides credentials directly. No OAuth flow, no verification step needed. For OAuth connectors, before activating a connected account, Scalekit confirms that the user who completed the OAuth consent is the same user your app intended to connect. This **user verification** step runs every time a connected account is authorized and prevents OAuth consent from activating on the wrong account. Choose a mode in **AgentKit** > **User Verification**: * **Custom user verification**: Your server confirms the authorizing user matches the user your app intended to connect. Use in production. Without this, any user who receives an authorization link can activate a connected account (including the wrong one). * **Scalekit users only**: Scalekit checks that the authorizing user is signed in to your Scalekit dashboard. No code required. Use during development and internal testing when all users are already on your team. ![AgentKit User Verification showing Custom user verifier and Scalekit users only](/.netlify/images?url=_astro%2Fuser-verification-config.R9EpQz_E.png\&w=2224\&h=1590\&dpl=6aaa70ad2ea7b40008ad2afd) Your application implements the verify step. End users never interact with Scalekit directly. When the user finishes OAuth, Scalekit redirects to your verify URL with `auth_request_id` and `state` params. Your route reads the user from your session, calls Scalekit’s verify API with the `auth_request_id` and the original `identifier`, and if they match, the connected account activates. ## Implement verification in your app [Section titled “Implement verification in your app”](#implement-verification-in-your-app) If you haven’t installed the SDK yet, see the [quickstart](/agentkit/quickstart/). ### Generate the authorization link [Section titled “Generate the authorization link”](#generate-the-authorization-link) Pass these fields when creating the authorization link: | Field | Description | | ----------------- | ------------------------------------------------------------------------------------------------- | | `identifier` | **Required.** Your user’s ID or email. Scalekit stores this and checks it matches at verify time. | | `user_verify_url` | **Required.** Your callback URL; Scalekit redirects the user here after OAuth completes. | | `state` | **Recommended.** A random value to prevent CSRF. | * Python ```python 1 import secrets 2 3 # Generate a state value to prevent CSRF 4 state = secrets.token_urlsafe(32) 5 # Store state in a secure, HTTP-only cookie to validate on callback 6 7 response = scalekit_client.actions.get_authorization_link( 8 connection_name=connector, 9 identifier=user_id, 10 user_verify_url="https://app.yourapp.com/user/verify", 11 state=state, 12 ) ``` * Node.js ```typescript 1 import crypto from 'node:crypto'; 2 3 // Generate a state value to prevent CSRF 4 const state = crypto.randomUUID(); 5 // Store state in a secure, HTTP-only cookie to validate on callback 6 7 const { link } = await scalekit.actions.getAuthorizationLink({ 8 identifier: userId, 9 connectionName: connector, 10 userVerifyUrl: 'https://app.yourapp.com/user/verify', 11 state, 12 }); ``` ### Handle the verification callback [Section titled “Handle the verification callback”](#handle-the-verification-callback) After OAuth completes, Scalekit redirects to your `user_verify_url`: ```http 1 GET https://app.yourapp.com/user/verify?auth_request_id=req_xyz&state= ``` Validate `state` against your cookie, then call Scalekit’s verify endpoint server-side. Never trust query params for identity Read the user’s identity from your own session, not from the URL. Use `state` for session correlation only. * Python ```python 1 # 1. Validate state from query param matches state in cookie 2 # 2. Read user identity from your session, not from the URL 3 4 response = scalekit_client.actions.verify_connected_account_user( 5 auth_request_id=auth_request_id, 6 identifier=user_id, # must match what was stored at link creation 7 ) 8 # On success: redirect to response.post_user_verify_redirect_url ``` * Node.js ```typescript 1 // 1. Validate state from query param matches state in cookie 2 // 2. Read user identity from your session, not from the URL 3 4 const { postUserVerifyRedirectUrl } = 5 await scalekit.actions.verifyConnectedAccountUser({ 6 authRequestId: auth_request_id, 7 identifier: userId, // must match what was stored at link creation 8 }); 9 // On success: redirect to postUserVerifyRedirectUrl ``` On success, the connected account is activated. Redirect the user using `post_user_verify_redirect_url`. ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) --- # DOCUMENT BOUNDARY --- # User authentication flow > Learn how Scalekit routes users through authentication based on login method and organization SSO policies. The user’s authentication journey on the hosted login page can differ based on the **login method** they choose and the **organization policies** configured in Scalekit. ## Organization policies [Section titled “Organization policies”](#organization-policies) Organizations can enforce Enterprise SSO for their users. An organization must create an enabled [SSO connection](/authenticate/auth-methods/enterprise-sso/) and add [organization domains](/authenticate/manage-users-orgs/organization-domains/). Scalekit uses **Home Realm Discovery (HRD)** to determine whether a user’s email domain matches a configured organization domain. When a match is found, the user is routed to that organization’s SSO identity provider. **Examples** * A user tries to log in as `user@samecorp.com` on the hosted login page. If `samecorp.com` is registered as an organization domain with SSO enabled, the user is redirected to that organization’s IdP to complete authentication. * A user tries to log in with Google as `user@samecorp.com` on the hosted login page. If `samecorp.com` is registered as an organization domain with SSO enabled, the user is redirected to that organization’s IdP after returning from Google. ## Login method–specific behavior [Section titled “Login method–specific behavior”](#login-methodspecific-behavior) Scalekit allows users to choose different login methods on the hosted login page. The timing of organization domain checks differs slightly by method, but the rules remain consistent. ### Social login [Section titled “Social login”](#social-login) * User authenticates with a social IdP (e.g., Google, GitHub). * Scalekit evaluates the user’s email after social auth completes. * Home Realm Discovery (HRD) checks whether the email domain matches an organization domain. * **Domain match:** User is redirected to the organization’s SSO IdP. * **No match:** Authentication completes. This ensures that enterprise users must complete SSO authentication even if they initially choose social login. ### Passkey login [Section titled “Passkey login”](#passkey-login) * User authenticates using a passkey. * Authentication succeeds immediately. * Scalekit performs Home Realm Discovery (HRD) to check the email domain. * **Domain match:** User is redirected to SSO. * **No match:** Authentication completes. Passkeys authenticate the user, but do not override organization SSO policy. ### Email-based login [Section titled “Email-based login”](#email-based-login) * User enters their email address. * Home Realm Discovery (HRD) runs **before authentication** to check the email domain. * **Domain match:** User is redirected to SSO. * **No match:** Scalekit performs OTP or magic link verification, then authentication completes. ### Authentication flow [Section titled “Authentication flow”](#authentication-flow) This diagram shows the different variations of user’s authentication journey on the hosted login page. *** ## Enterprise SSO Trust model [Section titled “Enterprise SSO Trust model”](#enterprise-sso-trust-model) Most enterprise identity providers (IdPs) like Okta or Microsoft Entra do not prove that a user actually controls the email inbox they sign in with. They only assert an email address in the SAML/OIDC token. Because of this, when a user logs in via Enterprise SSO, Scalekit does not automatically treat that SSO connection as a trusted source of email ownership. Since Scalekit cannot be sure that the SSO user truly owns the email address, the user is taken through an email ownership check (magic link or OTP) to prove control of that inbox. After the user successfully verifies their email, that SSO connection is marked as a verified channel for that specific user, and they do not need to verify email ownership again on subsequent logins via the same connection. If you want an Enterprise SSO connection to be treated as a trusted provider for a specific domain, you can assign one or more domains to the organization. Then, for users logging in via that Enterprise SSO connection whose email address matches one of the configured domains, Scalekit skips additional email ownership verification. | SSO trust case | Example | Result | | -------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | | Trusted SSO | Org has added `acmecorp.com` in organization domain. User authenticates as `user@acmecorp.com` with organization SSO. | Email ownership trusted | | Untrusted SSO | Org has added `acmecorp.com` in organization domain and user authenticates as `user@foocorp.com` with organization SSO. | Email ownership not trusted → Additional verification required | *** ## Forcing SSO from your application [Section titled “Forcing SSO from your application”](#forcing-sso-from-your-application) Your app can override Home Realm Discovery (HRD) by passing ‎`organization_id` or ‎`connection_id` in the authentication request ↗ to Scalekit. When you do this: * Scalekit skips HRD and redirects the user directly to the specified SSO IdP. * After SSO authentication completes, Scalekit checks whether the user’s email domain matches one of the organization domains configured on that SSO connection. * **Domain match**: authentication completes. * **No match**: Scalekit requires additional verification (OTP or magic link) before completing authentication. ## IdP‑initiated SSO [Section titled “IdP‑initiated SSO”](#idpinitiated-sso) In IdP‑initiated SSO, authentication starts at the identity provider instead of your application or the hosted login page. After the IdP authenticates the user and redirects to Scalekit, Scalekit evaluates email ownership trust: * If the user’s email domain matches one of the organization domains configured on the SSO connection, authentication completes. * If the email domain does not match, Scalekit requires additional verification (OTP or magic link) before completing authentication. This workflow ensures IdP‑initiated flows follow the same email ownership and trust guarantees as app‑initiated SSO *** ## Account linking [Section titled “Account linking”](#account-linking) ### What happens [Section titled “What happens”](#what-happens) Scalekit maintains a single user record per email address. For example, if a user first authenticates with passwordless login (magic link/OTP) and later uses Google or Enterprise SSO, Scalekit links both identities to the same user record. These identities are stored on the user object for your app to read if needed. This avoids duplicate users when people switch authentication methods. ### Why it is safe [Section titled “Why it is safe”](#why-it-is-safe) Scalekit only treats an SSO IdP as a trusted source of email ownership when: * the authenticated email domain matches one of the organization domains configured on the SSO connection, or * the user has previously proven email ownership via magic link or OTP. Because the organization has proven domain ownership, and/or the user has proven inbox control, emails from that SSO connection are treated as valid. This prevents attackers from linking identities unless email ownership has been verified through trusted mechanisms. --- # DOCUMENT BOUNDARY --- # Implement enterprise SSO > How to implement enterprise SSO for your application Enterprise single sign-on (SSO) enables users to authenticate using their organization’s identity provider (IdP), such as Okta, Azure AD, or Google Workspace. [After completing the quickstart](/authenticate/fsa/quickstart/), follow this guide to implement SSO for an organization, streamline admin onboarding, enforce login requirements, and validate your configuration. 1. ## Enable SSO for the organization [Section titled “Enable SSO for the organization”](#enable-sso-for-the-organization) When a user signs up for your application, Scalekit automatically creates an organization and assigns an admin role to the user. Provide an option in your user interface to enable SSO for the organization or workspace. Here’s how you can do that with Scalekit. Use the following SDK method to activate SSO for the organization: * Node.js Enable SSO ```javascript const settings = { features: [ { name: 'sso', enabled: true, } ], }; await scalekit.organization.updateOrganizationSettings( '', // Get this from the idToken or accessToken settings ); ``` * Python Enable SSO ```python settings = [ { "name": "sso", "enabled": True } ] scalekit.organization.update_organization_settings( organization_id='', # Get this from the idToken or accessToken settings=settings ) ``` * Java Enable SSO ```java OrganizationSettingsFeature featureSSO = OrganizationSettingsFeature.newBuilder() .setName("sso") .setEnabled(true) .build(); updatedOrganization = scalekitClient.organizations() .updateOrganizationSettings(organizationId, List.of(featureSSO)); ``` * Go Enable SSO ```go settings := OrganizationSettings{ Features: []Feature{ { Name: "sso", Enabled: true, }, }, } organization, err := sc.Organization().UpdateOrganizationSettings(ctx, organizationId, settings) if err != nil { // Handle error } ``` You can also enable this from the [organization settings](/authenticate/fsa/user-management-settings/) in the Scalekit dashboard. 2. ## Enable admin portal for enterprise customer onboarding [Section titled “Enable admin portal for enterprise customer onboarding”](#enable-admin-portal-for-enterprise-customer-onboarding) After SSO is enabled for that organization, provide a method for configuring a SSO connection with the organization’s identity provider. Scalekit offers two primary approaches: * Generate a link to the admin portal from the Scalekit dashboard and share it with organization admins via your usual channels. * Or embed the admin portal in your application in an inline frame so administrators can configure their IdP without leaving your app. [See how to onboard enterprise customers](/sso/guides/onboard-enterprise-customers/) 3. ## Identify and enforce SSO for organization users [Section titled “Identify and enforce SSO for organization users”](#identify-and-enforce-sso-for-organization-users) Administrators typically register [organization-owned domains](/authenticate/manage-users-orgs/organization-domains/) through the admin portal. When a user attempts to sign in with an email address matching a registered domain, they are automatically redirected to their organization’s designated identity provider for authentication. This is also known as **Home Realm Discovery**. **Organization domains** automatically route users to the correct SSO connection based on their email address. When a user signs in with an email domain that matches a registered organization domain, Scalekit redirects them to that organization’s SSO provider and enforces SSO login. For example, if an organization registers `megacorp.org`, any user signing in with an `joe@megacorp.org` email address is redirected to Megacorp’s SSO provider. ![Scalekit organization overview with the Organization Domains section showing a verified domain used for Home Realm Discovery](/.netlify/images?url=_astro%2Forganization_domain.CYaGBzer.png\&w=2940\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) Navigate to **Dashboard > Organizations** and select the target organization > **Overview** > **Organization Domains** section to register organization domains. 4. ## Test your SSO integration [Section titled “Test your SSO integration”](#test-your-sso-integration) Scalekit offers a “Test Organization” feature that enables SSO flow validation without requiring test accounts from your customers’ identity providers. To quickly test the integration, enter an email address using the domains `joe@example.com` or `jane@example.org`. This will trigger a redirect to the IdP simulator, which serves as the test organization’s identity provider for authentication. For a comprehensive step-by-step walkthrough, refer to the [Test SSO integration guide](/sso/guides/test-sso/). --- # DOCUMENT BOUNDARY --- # Add passkeys login method > Enable passkey authentication for your users Passkeys replace passwords with biometric authentication (fingerprint, face recognition) or device PINs. Built on FIDO® standards (WebAuthn and CTAP), passkeys offer superior security by eliminating phishing and credential stuffing vulnerabilities, while also providing a seamless one-tap login experience. Unlike traditional authentication methods, passkeys sync across devices, removing the need for multiple enrollments and providing better recovery options when devices are lost. Your [existing Scalekit integration](/authenticate/fsa/quickstart) already supports passkeys. To implement, enable passkeys in the Scalekit dashboard and leverage Scalekit’s built-in user passkey registration functionality. 1. ## Enable passkeys in the Scalekit dashboard [Section titled “Enable passkeys in the Scalekit dashboard”](#enable-passkeys-in-the-scalekit-dashboard) Go to Scalekit Dashboard > Authentication > Auth methods > Passkeys and click “Enable” ![Enable passkeys button in Scalekit settings](/.netlify/images?url=_astro%2Fenable-btn.C08G8Owj.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) 2. ## Manage passkey registration [Section titled “Manage passkey registration”](#manage-passkey-registration) Let users manage passkeys just by redirecting them to Scalekit from your app (usually through a button in your app that says “Manage passkeys”), or building your own UI. #### Using Scalekit UI [Section titled “Using Scalekit UI”](#using-scalekit-ui) To enable users to register and manage their passkeys, redirect them to the Scalekit passkey registration page. ![Passkey registration page in Scalekit UI](/.netlify/images?url=_astro%2Fbetter-registration-page.CMqMT27T.png\&w=2968\&h=1397\&dpl=6aaa70ad2ea7b40008ad2afd) Construct the URL by appending `/ui/profile/passkeys` to your Scalekit environment URL Passkey Registration URL ```js /ui/profile/passkeys ``` This opens a page where users can: * Register new passkeys * Remove existing passkeys * View their registered passkeys To show the page on your own domain instead of the default Scalekit domain, configure a [branded custom domain](/guides/custom-domain). Users then see a URL such as `https://auth.yourapp.com/ui/profile/passkeys`. #### In your own UI [Section titled “In your own UI”](#in-your-own-ui) If you prefer to create a custom user interface for passkey management, Scalekit offers comprehensive APIs that enable you to build a personalized experience. These APIs allow you to list registered passkeys, rename them, and remove them entirely. However registration of passkeys is only supported through the Scalekit UI. * Node.js List user's passkeys ```js // : fetch from Access Token or ID Token after identity verification const res = await fetch( '/api/v1/webauthn/credentials?user_id=', { headers: { Authorization: 'Bearer ' } } ); const data = await res.json(); console.log(data); ``` Rename a passkey ```js // : obtained from list response (id of each passkey) await fetch('/api/v1/webauthn/credentials/', { method: 'PATCH', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' }, body: JSON.stringify({ display_name: '' }) }); ``` Remove a passkey ```js // : obtained from list response (id of each passkey) await fetch('/api/v1/webauthn/credentials/', { method: 'DELETE', headers: { Authorization: 'Bearer ' } }); ``` * Python List user's passkeys ```python import requests # : fetch from access token or ID token after identity verification r = requests.get( '/api/v1/webauthn/credentials', params={'user_id': ''}, headers={'Authorization': 'Bearer '} ) print(r.json()) ``` Rename a passkey ```python import requests # : obtained from list response (id of each passkey) requests.patch( '/api/v1/webauthn/credentials/', json={'display_name': ''}, headers={'Authorization': 'Bearer '} ) ``` Remove a passkey ```python import requests # : obtained from list response (id of each passkey) requests.delete( '/api/v1/webauthn/credentials/', headers={'Authorization': 'Bearer '} ) ``` * Java List user's passkeys ```java var client = java.net.http.HttpClient.newHttpClient(); // : fetch from Access Token or ID Token after identity verification var req = java.net.http.HttpRequest.newBuilder( java.net.URI.create("/api/v1/webauthn/credentials?user_id=") ) .header("Authorization", "Bearer ") .GET().build(); var res = client.send(req, java.net.http.HttpResponse.BodyHandlers.ofString()); System.out.println(res.body()); ``` Rename a passkey ```java var client = java.net.http.HttpClient.newHttpClient(); var body = "{\"display_name\":\"\"}"; // : obtained from list response (id of each passkey) var req = java.net.http.HttpRequest.newBuilder( java.net.URI.create("/api/v1/webauthn/credentials/") ) .header("Authorization", "Bearer ") .header("Content-Type","application/json") .method("PATCH", java.net.http.HttpRequest.BodyPublishers.ofString(body)) .build(); client.send(req, java.net.http.HttpResponse.BodyHandlers.discarding()); ``` Remove a passkey ```java var client = java.net.http.HttpClient.newHttpClient(); // : obtained from list response (id of each passkey) var req = java.net.http.HttpRequest.newBuilder( java.net.URI.create("/api/v1/webauthn/credentials/") ) .header("Authorization", "Bearer ") .DELETE().build(); client.send(req, java.net.http.HttpResponse.BodyHandlers.discarding()); ``` * Go List user's passkeys ```go // imports: net/http, io, fmt // : fetch from access token or ID token after identity verification req, _ := http.NewRequest("GET", "/api/v1/webauthn/credentials?user_id=", nil) req.Header.Set("Authorization", "Bearer ") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() b, _ := io.ReadAll(resp.Body) fmt.Println(string(b)) ``` Rename a passkey ```go // imports: net/http, bytes payload := bytes.NewBufferString(`{"display_name":""}`) // : obtained from list response (id of each passkey) req, _ := http.NewRequest("PATCH", "/api/v1/webauthn/credentials/", payload) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer ") http.DefaultClient.Do(req) ``` Remove a passkey ```go // imports: net/http // : obtained from list response (id of each passkey) req, _ := http.NewRequest("DELETE", "/api/v1/webauthn/credentials/", nil) req.Header.Set("Authorization", "Bearer ") http.DefaultClient.Do(req) ``` 3. ## Users can log in with passkeys [Section titled “Users can log in with passkeys”](#users-can-log-in-with-passkeys) Users who have registered passkeys can log in with them. This time when login page shows, users can select “Passkey” as the authentication method. ![Login with passkey option on sign-in page](/.netlify/images?url=_astro%2Flogin-with-passkey.ZZ6-wNXH.png\&w=2978\&h=1800\&dpl=6aaa70ad2ea7b40008ad2afd) During sign-up, you’ll continue to use established authentication methods like [verification codes, magic links](/authenticate/auth-methods/passwordless/) or [social logins](/authenticate/auth-methods/social-logins/). Once a user is registered, they can then add passkeys as an additional, convenient login option. --- # DOCUMENT BOUNDARY --- # Sign in with magic link or Email OTP > Enable passwordless sign-in with email verification codes or magic links Configure Magic Link & OTP to enable passwordless authentication for your application. After completing the [quickstart guide](/authenticate/fsa/quickstart/), set up email verification codes or magic links so users can sign in without passwords. Switch between those passwordless methods without modifying any code: | Method | How it works | Best for | | ------------------------------ | ---------------------------------------------------------------- | -------------------------------------------- | | Verification code | Users receive a one-time code via email and enter it in your app | Applications requiring explicit verification | | Magic link | Users click a link in their email to authenticate | Quick, frictionless sign-in | | Magic link + Verification code | Users choose either method | Maximum flexibility and user choice | ## Configure magic link or OTP [Section titled “Configure magic link or OTP”](#configure-magic-link-or-otp) In the Scalekit dashboard, go to **Authentication > Auth methods > Magic Link & OTP** ![Scalekit dashboard Magic link & OTP settings showing the login method selection and expiry period fields](/.netlify/images?url=_astro%2F1.1jnMxeBv.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) 1. ### Select authentication method [Section titled “Select authentication method”](#select-authentication-method) Choose one of three methods: * **Verification code** - Users enter a 6-digit code sent to their email * **Magic link** - Users click a link in their email to authenticate * **Magic link + Verification code** - Users can choose either method 2. ### Set expiry period [Section titled “Set expiry period”](#set-expiry-period) Configure how long verification codes and magic links remain valid: * **Default**: 300 seconds (5 minutes) * **Range**: 60 to 3600 seconds * **Recommendation**: 300 seconds balances security and usability ## Enforce same browser origin [Section titled “Enforce same browser origin”](#enforce-same-browser-origin) When enforcing same browser origin, users are required to complete magic link authentication within the same browser where they initiated the login process. This security feature is particularly recommended for applications dealing with sensitive data or financial transactions, as it adds an extra layer of protection against potential unauthorized access attempts. **Example scenario**: A healthcare app where a user requests a magic link on their laptop. If someone intercepts the email and tries to open it on a different device, the authentication fails. ## Regenerate credentials on resend [Section titled “Regenerate credentials on resend”](#regenerate-credentials-on-resend) When a user requests a new Magic Link or Email OTP, the system generates a fresh code or link while automatically invalidating the previous one. This approach is recommended for all applications as a critical security measure to prevent potential misuse of compromised credentials. **Example scenario**: A user requests a verification code but doesn’t receive it. They request a new code. With this setting enabled, the first code becomes invalid, preventing unauthorized access if the original email was intercepted. --- # DOCUMENT BOUNDARY --- # Add social login to your app > Implement authentication with Google, Microsoft, GitHub, and other social providers First, complete the [quickstart guide](/authenticate/fsa/quickstart/) to integrate Scalekit auth into your application. Scalekit natively supports OAuth 2.0, enabling you to easily configure social login providers that will automatically appear as authentication options on your login page. 1. ## Configure social login providers [Section titled “Configure social login providers”](#configure-social-login-providers) Google login is pre-configured in all development environments for simplified testing. You can integrate additional social login providers by setting up your own connection credentials with each provider. Navigate to **Authentication** > **Auth Methods** > **Social logins** in your dashboard to configure these settings ### Google Enable users to sign in with their Google accounts using OAuth 2.0 [Setup →](/guides/integrations/social-connections/google) ### GitHub Allow users to authenticate using their GitHub credentials [Setup →](/guides/integrations/social-connections/github) ### Microsoft Integrate Microsoft accounts for seamless user authentication [Setup →](/guides/integrations/social-connections/microsoft) ### GitLab Enable GitLab-based authentication for your application [Setup →](/guides/integrations/social-connections/gitlab) ### LinkedIn Let users sign in with their LinkedIn accounts using OAuth 2.0 [Setup →](/guides/integrations/social-connections/linkedin) ### Salesforce Enable Salesforce-based authentication for your application [Setup →](/guides/integrations/social-connections/salesforce) 2. ## Test the social connection [Section titled “Test the social connection”](#test-the-social-connection) After configuration, test the social connection by clicking on “Test Connection” in the dashboard. You will be redirected to the provider’s consent screen to authorize access. A summary table will show the information that will be sent to your app. ![Scalekit Test Connection panel for Google showing sign-in test instructions, common error causes, and a Retry Test button](/.netlify/images?url=_astro%2Ftest-connection.8nGwOF1-.png\&w=2468\&h=1374\&dpl=6aaa70ad2ea7b40008ad2afd) ## Access social login options on your login page [Section titled “Access social login options on your login page”](#access-social-login-options-on-your-login-page) Your application now supports social logins. Begin the [login process](/authenticate/fsa/implement-login/) to experience the available social login options. Users can authenticate using providers like Google, GitHub, Microsoft, and any others you have set up. --- # DOCUMENT BOUNDARY --- # Assign roles to users > Learn how to assign roles to users in your application using to dashboard, SDK, or automated provisioning After registering roles and permissions for your application, Scalekit provides multiple ways to assign roles to users. These roles allow your app to make the access control decisions as scalekit sends them to your app in the access token. ## Auto assign roles as users join organizations [Section titled “Auto assign roles as users join organizations”](#auto-assign-roles-as-users-join-organizations) By default, the organization creator automatically receives the `admin` role, while users who join later receive the `member` role. You can customize these defaults to match your application’s security requirements. For instance, in a CRM system, you may want to set the default role for new members to a read-only role like `viewer` to prevent accidental data modifications. 1. Go to **Dashboard** > **Roles & Permissions** > **Roles** tab 2. Select the roles available and choose defaults for organization creator and member ![Roles & Permissions page listing admin, member, and viewer roles, with a Default Roles panel for choosing the creator and member roles](/.netlify/images?url=_astro%2Ffull-page-highlighth-defaults.Cs9-9nAm.png\&w=3098\&h=1896\&dpl=6aaa70ad2ea7b40008ad2afd) This automatically assigns these roles to every users who joins any organization in your Scalekit environment. ## Set a default role for new organization members [Section titled “Set a default role for new organization members”](#set-a-default-role-for-new-organization-members) You can also configure a default role that is automatically assigned to users who join a specific organization. This organization-level setting **overrides** the application-level default role described above, allowing finer-grained control per organization. ![Organization roles view with a Default organization role dropdown for assigning a role to new users joining that organization](/.netlify/images?url=_astro%2Fdefault_org_member_role.DzatyaVW.png\&w=2932\&h=1588\&dpl=6aaa70ad2ea7b40008ad2afd) ## Let users assign roles to others API [Section titled “Let users assign roles to others ”](#let-users-assign-roles-to-others-) Enable organization administrators to manage user roles directly within your application. By building features like “Change role” or “Assign permissions” into your app, you can provide a management experience without requiring administrators to leave your app. To implement role assignment functionality, follow these essential prerequisites: 1. **Verify administrator permissions**: Ensure the user performing the role assignment has the `admin` role or an equivalent role with the necessary permissions. Check the `permissions` property in their access token to confirm they have role management capabilities. * Node.js Verify permissions ```javascript 1 // Decode JWT and check admin permissions 2 const decodedToken = decodeJWT(adminAccessToken); 3 4 // Check if user has admin role or required permissions 5 const isAdmin = decodedToken.roles.includes('admin'); 6 const hasPermission = decodedToken.permissions?.includes('users.write') || 7 decodedToken.permissions?.includes('roles.assign'); 8 9 if (!isAdmin && !hasPermission) { 10 throw new Error('Insufficient permissions to assign roles'); 11 } ``` * Python Verify permissions ```python 1 # Decode JWT and check admin permissions 2 decoded_token = decode_jwt(access_token) 3 4 # Check if user has admin role or required permissions 5 is_admin = 'admin' in decoded_token.get('roles', []) 6 has_permission = any(perm in decoded_token.get('permissions', []) 7 for perm in ['users.write', 'roles.assign']) 8 9 if not is_admin and not has_permission: 10 raise PermissionError("Insufficient permissions to assign roles") ``` * Go Verify permissions ```go 1 // Decode JWT and check admin permissions 2 decodedToken, err := decodeJWT(accessToken) 3 if err != nil { 4 return ValidationResult{Success: false, Error: "Invalid token"} 5 } 6 7 // Check if user has admin role or required permissions 8 roles := decodedToken["roles"].([]interface{}) 9 permissions := decodedToken["permissions"].([]interface{}) 10 11 isAdmin := false 12 hasPermission := false 13 14 for _, role := range roles { 15 if role == "admin" { 16 isAdmin = true 17 break 18 } 19 } 20 21 for _, perm := range permissions { 22 if perm == "users.write" || perm == "roles.assign" { 23 hasPermission = true 24 break 25 } 26 } 27 28 if !isAdmin && !hasPermission { 29 return ValidationResult{Success: false, Error: "Insufficient permissions"} 30 } ``` * Java Verify permissions ```java 1 // Decode JWT and check admin permissions 2 Claims decodedToken = decodeJWT(accessToken); 3 4 @SuppressWarnings("unchecked") 5 List userRoles = (List) decodedToken.get("roles"); 6 @SuppressWarnings("unchecked") 7 List permissions = (List) decodedToken.get("permissions"); 8 9 // Check if user has admin role or required permissions 10 boolean isAdmin = userRoles != null && userRoles.contains("admin"); 11 boolean hasPermission = permissions != null && 12 (permissions.contains("users.write") || permissions.contains("roles.assign")); 13 14 if (!isAdmin && !hasPermission) { 15 throw new SecurityException("Insufficient permissions to assign roles"); 16 } ``` 2. **Collect required identifiers**: Gather the necessary parameters for the API call: * `user_id`: The unique identifier of the user whose role you’re changing * `organization_id`: The organization where the role assignment applies * `roles`: An array of role names to assign to the user - Node.js Collect and validate identifiers ```javascript 1 // Structure and validate role assignment data 2 const roleAssignmentData = { 3 user_id: targetUserId, 4 organization_id: targetOrgId, 5 roles: newRoles, 6 // Additional metadata for auditing 7 performed_by: decodedToken.sub, 8 timestamp: new Date().toISOString() 9 }; 10 11 // Validate required fields 12 if (!roleAssignmentData.user_id || !roleAssignmentData.organization_id || !roleAssignmentData.roles) { 13 throw new Error('Missing required identifiers for role assignment'); 14 } ``` - Python Collect and validate identifiers ```python 1 # Structure and validate role assignment data 2 role_assignment_data = { 3 'user_id': target_user_id, 4 'organization_id': target_org_id, 5 'roles': new_roles, 6 # Additional metadata for auditing 7 'performed_by': decoded_token.get('sub'), 8 'timestamp': datetime.utcnow().isoformat() 9 } 10 11 # Validate required fields 12 if not all([role_assignment_data['user_id'], 13 role_assignment_data['organization_id'], 14 role_assignment_data['roles']]): 15 raise ValueError("Missing required identifiers for role assignment") ``` - Go Collect and validate identifiers ```go 1 // Structure and validate role assignment data 2 roleAssignmentData := map[string]interface{}{ 3 "user_id": req.UserID, 4 "organization_id": req.OrganizationID, 5 "roles": req.Roles, 6 // Additional metadata for auditing 7 "performed_by": decodedToken["sub"], 8 "timestamp": time.Now().UTC().Format(time.RFC3339), 9 } 10 11 // Validate required fields 12 if req.UserID == "" || req.OrganizationID == "" || len(req.Roles) == 0 { 13 return ValidationResult{Success: false, Error: "Missing required identifiers"} 14 } ``` - Java Collect and validate identifiers ```java 1 // Structure and validate role assignment data 2 Map roleAssignmentData = new HashMap<>(); 3 roleAssignmentData.put("user_id", request.userId); 4 roleAssignmentData.put("organization_id", request.organizationId); 5 roleAssignmentData.put("roles", request.roles); 6 7 // Additional metadata for auditing 8 roleAssignmentData.put("performed_by", decodedToken.getSubject()); 9 roleAssignmentData.put("timestamp", Instant.now().toString()); 10 11 // Validate required fields 12 if (request.userId == null || request.organizationId == null || request.roles == null) { 13 throw new IllegalArgumentException("Missing required identifiers for role assignment"); 14 } ``` 3. **Call Scalekit SDK to update user role**: Use the validated data to make the API call that assigns the new roles to the user through the Scalekit membership update endpoint. * Node.js Update user role with Scalekit SDK ```javascript 1 // Use case: Update user membership after validation 2 const validationResult = await prepareRoleAssignment( 3 adminAccessToken, 4 targetUserId, 5 targetOrgId, 6 newRoles 7 ); 8 9 if (!validationResult.success) { 10 return res.status(403).json({ error: validationResult.error }); 11 } 12 13 // Initialize Scalekit client (reference installation guide for setup) 14 const scalekit = new ScalekitClient( 15 process.env.SCALEKIT_ENVIRONMENT_URL, 16 process.env.SCALEKIT_CLIENT_ID, 17 process.env.SCALEKIT_CLIENT_SECRET 18 ); 19 20 // Make the API call to update user roles 21 try { 22 const result = await scalekit.user.updateMembership({ 23 user_id: validationResult.data.user_id, 24 organization_id: validationResult.data.organization_id, 25 roles: validationResult.data.roles 26 }); 27 28 console.log(`Role assigned successfully:`, result); 29 return res.json({ 30 success: true, 31 message: "Role updated successfully", 32 data: result 33 }); 34 } catch (error) { 35 console.error(`Failed to assign role: ${error.message}`); 36 return res.status(500).json({ 37 error: "Failed to update role", 38 details: error.message 39 }); 40 } ``` * Python Update user role with Scalekit SDK ```python 1 # Use case: Update user membership after validation 2 validation_result = prepare_role_assignment( 3 access_token, 4 target_user_id, 5 target_org_id, 6 new_roles 7 ) 8 9 if not validation_result['success']: 10 return jsonify({'error': validation_result['error']}), 403 11 12 # Initialize Scalekit client (reference installation guide for setup) 13 scalekit_client = ScalekitClient( 14 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 15 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 16 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 17 ) 18 19 # Make the API call to update user roles 20 try: 21 from scalekit.v1.users.users_pb2 import UpdateMembershipRequest 22 23 request = UpdateMembershipRequest( 24 user_id=validation_result['data']['user_id'], 25 organization_id=validation_result['data']['organization_id'], 26 roles=validation_result['data']['roles'] 27 ) 28 29 result = scalekit_client.users.update_membership(request=request) 30 print(f"Role assigned successfully: {result}") 31 32 return jsonify({ 33 'success': True, 34 'message': 'Role updated successfully', 35 'data': str(result) 36 }) 37 38 except Exception as error: 39 print(f"Failed to assign role: {error}") 40 return jsonify({ 41 'error': 'Failed to update role', 42 'details': str(error) 43 }), 500 ``` * Go Update user role with Scalekit SDK ```go 1 // Use case: Update user membership after validation 2 validationResult := prepareRoleAssignment(ctx, accessToken, req) 3 4 if !validationResult.Success { 5 http.Error(w, validationResult.Error, http.StatusForbidden) 6 return 7 } 8 9 // Initialize Scalekit client (reference installation guide for setup) 10 scalekitClient := scalekit.NewScalekitClient( 11 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 12 os.Getenv("SCALEKIT_CLIENT_ID"), 13 os.Getenv("SCALEKIT_CLIENT_SECRET"), 14 ) 15 16 // Make the API call to update user roles 17 data := validationResult.Data.(map[string]interface{}) 18 updateRequest := &scalekit.UpdateMembershipRequest{ 19 UserId: data["user_id"].(string), 20 OrganizationId: data["organization_id"].(string), 21 Roles: data["roles"].([]string), 22 } 23 24 result, err := scalekitClient.Membership().UpdateMembership(ctx, updateRequest) 25 if err != nil { 26 log.Printf("Failed to assign role: %v", err) 27 http.Error(w, "Failed to update role", http.StatusInternalServerError) 28 return 29 } 30 31 log.Printf("Role assigned successfully: %+v", result) 32 json.NewEncoder(w).Encode(map[string]interface{}{ 33 "success": true, 34 "message": "Role updated successfully", 35 "data": result, 36 }) ``` * Java Update user role with Scalekit SDK ```java 1 // Use case: Update user membership after validation 2 ValidationResult validationResult = prepareRoleAssignment(accessToken, request); 3 4 if (!validationResult.success) { 5 return ResponseEntity.status(403).body(Map.of("error", validationResult.error)); 6 } 7 8 // Initialize Scalekit client (reference installation guide for setup) 9 ScalekitClient scalekitClient = new ScalekitClient( 10 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 11 System.getenv("SCALEKIT_CLIENT_ID"), 12 System.getenv("SCALEKIT_CLIENT_SECRET") 13 ); 14 15 // Make the API call to update user roles 16 try { 17 @SuppressWarnings("unchecked") 18 Map data = (Map) validationResult.data; 19 20 UpdateMembershipRequest updateRequest = UpdateMembershipRequest.newBuilder() 21 .setUserId((String) data.get("user_id")) 22 .setOrganizationId((String) data.get("organization_id")) 23 .addAllRoles((List) data.get("roles")) 24 .build(); 25 26 UpdateMembershipResponse response = scalekitClient.users().updateMembership(updateRequest); 27 System.out.println("Role assigned successfully: " + response); 28 29 return ResponseEntity.ok(Map.of( 30 "success", true, 31 "message", "Role updated successfully", 32 "data", response.toString() 33 )); 34 35 } catch (Exception e) { 36 System.err.println("Failed to assign role: " + e.getMessage()); 37 return ResponseEntity.status(500).body(Map.of( 38 "error", "Failed to update role", 39 "details", e.getMessage() 40 )); 41 } ``` 4. **Handle response and provide feedback**: Return appropriate success/error responses to the administrator and update your application’s UI accordingly. * Node.js Handle API response ```javascript 1 // Success response handling 2 if (result.success) { 3 // Update UI to reflect role change 4 await updateUserInterface(targetUserId, newRoles); 5 6 // Send notification to user (optional) 7 await notifyUserOfRoleChange(targetUserId, newRoles); 8 9 // Log the action for audit purposes 10 await logRoleChange({ 11 performed_by: decodedToken.sub, 12 target_user: targetUserId, 13 organization: targetOrgId, 14 old_roles: previousRoles, 15 new_roles: newRoles, 16 timestamp: new Date().toISOString() 17 }); 18 } ``` * Python Handle API response ```python 1 # Success response handling 2 if result.get('success'): 3 # Update UI to reflect role change 4 await update_user_interface(target_user_id, new_roles) 5 6 # Send notification to user (optional) 7 await notify_user_of_role_change(target_user_id, new_roles) 8 9 # Log the action for audit purposes 10 await log_role_change({ 11 'performed_by': decoded_token.get('sub'), 12 'target_user': target_user_id, 13 'organization': target_org_id, 14 'old_roles': previous_roles, 15 'new_roles': new_roles, 16 'timestamp': datetime.utcnow().isoformat() 17 }) ``` * Go Handle API response ```go 1 // Success response handling 2 if success { 3 // Update UI to reflect role change 4 updateUserInterface(targetUserID, newRoles) 5 6 // Send notification to user (optional) 7 notifyUserOfRoleChange(targetUserID, newRoles) 8 9 // Log the action for audit purposes 10 logRoleChange(map[string]interface{}{ 11 "performed_by": decodedToken["sub"], 12 "target_user": targetUserID, 13 "organization": targetOrgID, 14 "old_roles": previousRoles, 15 "new_roles": newRoles, 16 "timestamp": time.Now().UTC().Format(time.RFC3339), 17 }) 18 } ``` * Java Handle API response ```java 1 // Success response handling 2 if (response.getBody().containsKey("success") && 3 Boolean.TRUE.equals(response.getBody().get("success"))) { 4 5 // Update UI to reflect role change 6 updateUserInterface(targetUserId, newRoles); 7 8 // Send notification to user (optional) 9 notifyUserOfRoleChange(targetUserId, newRoles); 10 11 // Log the action for audit purposes 12 logRoleChange(Map.of( 13 "performed_by", decodedToken.getSubject(), 14 "target_user", targetUserId, 15 "organization", targetOrgId, 16 "old_roles", previousRoles, 17 "new_roles", newRoles, 18 "timestamp", Instant.now().toString() 19 )); 20 } ``` --- # DOCUMENT BOUNDARY --- # Create and manage roles and permissions > Set up roles and permissions to control access in your application Before writing any code, take a moment to plan your application’s authorization model. A well-designed structure for roles and permissions is crucial for security and maintainability. Start by considering the following questions: * What are the actions your users can perform? * How many distinct roles does your application need? Your application’s use cases will determine the answers. Here are a few common patterns: * **Simple roles**: Some applications, like an online whiteboarding tool, may only need a few roles with implicit permissions. For example, `Admin`, `Editor`, and `Viewer`. In this case, you might not even need to define granular permissions. * **Pre-defined roles and permissions**: Many applications have a fixed set of roles built from specific permissions. For a project management tool, you could define permissions like `projects:create` and `tasks:assign`, then group them into roles like `Project Manager` and `Team Member`. * **Customer-defined Roles**: For complex applications, you might allow organization owners to create custom roles with a specific set of permissions. These roles are specific to an organization rather than global to your application. Scalekit provides the flexibility to build authorization for any of these use cases. Once you have a clear plan, you can start creating your permissions and roles. Define the permissions your application needs by registering them with Scalekit. Use the `resource:action` format for clear, self-documenting permission names. You can skip this step, in case permissions may not fit your app’s authorization model. 1. ## Define the actions your users can perform as permissions [Section titled “Define the actions your users can perform as permissions”](#define-the-actions-your-users-can-perform-as-permissions) * Node.js Create permissions ```javascript 1 // Initialize Scalekit client 2 // Use case: Register all available actions in your project management app 3 import { ScalekitClient } from "@scalekit-sdk/node"; 4 5 const scalekit = new ScalekitClient( 6 process.env.SCALEKIT_ENVIRONMENT_URL, 7 process.env.SCALEKIT_CLIENT_ID, 8 process.env.SCALEKIT_CLIENT_SECRET 9 ); 10 11 // Define your application's permissions 12 const permissions = [ 13 { 14 name: "projects:create", 15 description: "Allows users to create new projects" 16 }, 17 { 18 name: "projects:read", 19 description: "Allows users to view project details" 20 }, 21 { 22 name: "projects:update", 23 description: "Allows users to modify existing projects" 24 }, 25 { 26 name: "projects:delete", 27 description: "Allows users to remove projects" 28 }, 29 { 30 name: "tasks:assign", 31 description: "Allows users to assign tasks to team members" 32 } 33 ]; 34 35 // Register each permission with Scalekit 36 for (const permission of permissions) { 37 await scalekit.permission.createPermission(permission); 38 console.log(`Created permission: ${permission.name}`); 39 } 40 41 // Your application's permissions are now registered with Scalekit ``` * Python Create permissions ```python 1 # Initialize Scalekit client 2 # Use case: Register all available actions in your project management app 3 from scalekit import ScalekitClient 4 5 scalekit_client = ScalekitClient( 6 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 7 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 8 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 9 ) 10 11 # Define your application's permissions 12 from scalekit.v1.roles.roles_pb2 import CreatePermission 13 14 permissions = [ 15 CreatePermission( 16 name="projects:create", 17 description="Allows users to create new projects" 18 ), 19 CreatePermission( 20 name="projects:read", 21 description="Allows users to view project details" 22 ), 23 CreatePermission( 24 name="projects:update", 25 description="Allows users to modify existing projects" 26 ), 27 CreatePermission( 28 name="projects:delete", 29 description="Allows users to remove projects" 30 ), 31 CreatePermission( 32 name="tasks:assign", 33 description="Allows users to assign tasks to team members" 34 ) 35 ] 36 37 # Register each permission with Scalekit 38 for permission in permissions: 39 scalekit_client.permissions.create_permission(permission=permission) 40 print(f"Created permission: {permission.name}") 41 42 # Your application's permissions are now registered with Scalekit ``` * Go Create permissions ```go 1 // Initialize Scalekit client 2 // Use case: Register all available actions in your project management app 3 package main 4 5 import ( 6 "context" 7 "log" 8 "github.com/scalekit-inc/scalekit-sdk-go" 9 ) 10 11 func main() { 12 sc := scalekit.NewScalekitClient( 13 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 14 os.Getenv("SCALEKIT_CLIENT_ID"), 15 os.Getenv("SCALEKIT_CLIENT_SECRET"), 16 ) 17 18 // Define your application's permissions 19 permissions := []*scalekit.CreatePermission{ 20 { 21 Name: "projects:create", 22 Description: "Allows users to create new projects", 23 }, 24 { 25 Name: "projects:read", 26 Description: "Allows users to view project details", 27 }, 28 { 29 Name: "projects:update", 30 Description: "Allows users to modify existing projects", 31 }, 32 { 33 Name: "projects:delete", 34 Description: "Allows users to remove projects", 35 }, 36 { 37 Name: "tasks:assign", 38 Description: "Allows users to assign tasks to team members", 39 }, 40 } 41 42 // Register each permission with Scalekit 43 for _, permission := range permissions { 44 _, err := sc.Permission().CreatePermission(ctx, permission) 45 if err != nil { 46 log.Printf("Failed to create permission: %s", permission.Name) 47 continue 48 } 49 fmt.Printf("Created permission: %s\n", permission.Name) 50 } 51 52 // Your application's permissions are now registered with Scalekit 53 } ``` * Java Create permissions ```java 1 // Initialize Scalekit client 2 // Use case: Register all available actions in your project management app 3 import com.scalekit.ScalekitClient; 4 import com.scalekit.grpc.scalekit.v1.roles.*; 5 6 ScalekitClient scalekitClient = new ScalekitClient( 7 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 8 System.getenv("SCALEKIT_CLIENT_ID"), 9 System.getenv("SCALEKIT_CLIENT_SECRET") 10 ); 11 12 // Define your application's permissions 13 List permissions = Arrays.asList( 14 CreatePermission.newBuilder() 15 .setName("projects:create") 16 .setDescription("Allows users to create new projects") 17 .build(), 18 CreatePermission.newBuilder() 19 .setName("projects:read") 20 .setDescription("Allows users to view project details") 21 .build(), 22 CreatePermission.newBuilder() 23 .setName("projects:update") 24 .setDescription("Allows users to modify existing projects") 25 .build(), 26 CreatePermission.newBuilder() 27 .setName("projects:delete") 28 .setDescription("Allows users to remove projects") 29 .build(), 30 CreatePermission.newBuilder() 31 .setName("tasks:assign") 32 .setDescription("Allows users to assign tasks to team members") 33 .build() 34 ); 35 36 // Register each permission with Scalekit 37 for (CreatePermission permission : permissions) { 38 try { 39 CreatePermissionRequest request = CreatePermissionRequest.newBuilder() 40 .setPermission(permission) 41 .build(); 42 43 scalekitClient.permissions().createPermission(request); 44 System.out.println("Created permission: " + permission.getName()); 45 } catch (Exception e) { 46 System.err.println("Error creating permission: " + e.getMessage()); 47 } 48 } 49 50 // Your application's permissions are now registered with Scalekit ``` 2. ## Register roles your applications will use [Section titled “Register roles your applications will use”](#register-roles-your-applications-will-use) Once you have defined permissions, group them into roles that match your application’s access patterns. * Node.js Create roles with permissions ```javascript 1 // Define roles with their associated permissions 2 // Use case: Create standard roles for your project management application 3 const roles = [ 4 { 5 name: 'project_admin', 6 display_name: 'Project Administrator', 7 description: 'Full access to manage projects and team members', 8 permissions: [ 9 'projects:create', 'projects:read', 'projects:update', 'projects:delete', 10 'tasks:assign' 11 ] 12 }, 13 { 14 name: 'project_manager', 15 display_name: 'Project Manager', 16 description: 'Can manage projects and assign tasks', 17 permissions: [ 18 'projects:create', 'projects:read', 'projects:update', 19 'tasks:assign' 20 ] 21 }, 22 { 23 name: 'team_member', 24 display_name: 'Team Member', 25 description: 'Can view projects and participate in tasks', 26 permissions: [ 27 'projects:read' 28 ] 29 } 30 ]; 31 32 // Register each role with Scalekit 33 for (const role of roles) { 34 await scalekit.role.createRole(role); 35 console.log(`Created role: ${role.name}`); 36 } 37 38 // Your application's roles are now registered with Scalekit ``` * Python Create roles with permissions ```python 1 # Define roles with their associated permissions 2 # Use case: Create standard roles for your project management application 3 from scalekit.v1.roles.roles_pb2 import CreateRole 4 5 roles = [ 6 CreateRole( 7 name="project_admin", 8 display_name="Project Administrator", 9 description="Full access to manage projects and team members", 10 permissions=["projects:create", "projects:read", "projects:update", "projects:delete", "tasks:assign"] 11 ), 12 CreateRole( 13 name="project_manager", 14 display_name="Project Manager", 15 description="Can manage projects and assign tasks", 16 permissions=["projects:create", "projects:read", "projects:update", "tasks:assign"] 17 ), 18 CreateRole( 19 name="team_member", 20 display_name="Team Member", 21 description="Can view projects and participate in tasks", 22 permissions=["projects:read"] 23 ) 24 ] 25 26 # Register each role with Scalekit 27 for role in roles: 28 scalekit_client.roles.create_role(role=role) 29 print(f"Created role: {role.name}") 30 31 # Your application's roles are now registered with Scalekit ``` * Go Create roles with permissions ```go 1 // Define roles with their associated permissions 2 // Use case: Create standard roles for your project management application 3 roles := []*scalekit.CreateRole{ 4 { 5 Name: "project_admin", 6 DisplayName: "Project Administrator", 7 Description: "Full access to manage projects and team members", 8 Permissions: []string{"projects:create", "projects:read", "projects:update", "projects:delete", "tasks:assign"}, 9 }, 10 { 11 Name: "project_manager", 12 DisplayName: "Project Manager", 13 Description: "Can manage projects and assign tasks", 14 Permissions: []string{"projects:create", "projects:read", "projects:update", "tasks:assign"}, 15 }, 16 { 17 Name: "team_member", 18 DisplayName: "Team Member", 19 Description: "Can view projects and participate in tasks", 20 Permissions: []string{"projects:read"}, 21 }, 22 } 23 24 // Register each role with Scalekit 25 for _, role := range roles { 26 _, err := sc.Role().CreateRole(ctx, role) 27 if err != nil { 28 log.Printf("Failed to create role: %s", role.Name) 29 continue 30 } 31 fmt.Printf("Created role: %s\n", role.Name) 32 } 33 34 // Your application's roles are now registered with Scalekit ``` * Java Create roles with permissions ```java 1 // Define roles with their associated permissions 2 // Use case: Create standard roles for your project management application 3 List roles = Arrays.asList( 4 CreateRole.newBuilder() 5 .setName("project_admin") 6 .setDisplayName("Project Administrator") 7 .setDescription("Full access to manage projects and team members") 8 .addAllPermissions(Arrays.asList("projects:create", "projects:read", "projects:update", "projects:delete", "tasks:assign")) 9 .build(), 10 CreateRole.newBuilder() 11 .setName("project_manager") 12 .setDisplayName("Project Manager") 13 .setDescription("Can manage projects and assign tasks") 14 .addAllPermissions(Arrays.asList("projects:create", "projects:read", "projects:update", "tasks:assign")) 15 .build(), 16 CreateRole.newBuilder() 17 .setName("team_member") 18 .setDisplayName("Team Member") 19 .setDescription("Can view projects and participate in tasks") 20 .addPermissions("projects:read") 21 .build() 22 ); 23 24 // Register each role with Scalekit 25 for (CreateRole role : roles) { 26 try { 27 CreateRoleRequest request = CreateRoleRequest.newBuilder() 28 .setRole(role) 29 .build(); 30 31 scalekitClient.roles().createRole(request); 32 System.out.println("Created role: " + role.getName()); 33 } catch (Exception e) { 34 System.err.println("Error creating role: " + e.getMessage()); 35 } 36 } 37 38 // Your application's roles are now registered with Scalekit ``` ## Inherit permissions through roles [Section titled “Inherit permissions through roles”](#inherit-permissions-through-roles) Large applications with extensive feature sets require sophisticated role and permission management. Scalekit enables role inheritance, allowing you to create a hierarchical access control system. Permissions can be grouped into roles, and new roles can be derived from existing base roles, providing a flexible and scalable approach to defining user access. Role assignment in Scalekit automatically grants a user all permissions defined within that role. This is how you can implement use it: 1. Your app defines the permissions and assigns to a role. Let’s say `viewer` role. 2. When creating new role called `editor`, you specify that it inherits the permissions from the `viewer` role. 3. When creating new role called `project_owner`, you specify that it inherits the permissions from the `editor` role. Take a look at our [Roles and Permissions APIs](https://docs.scalekit.com/apis/#tag/roles/GET/api/v1/roles). ## Manage roles and permissions in the dashboard [Section titled “Manage roles and permissions in the dashboard”](#manage-roles-and-permissions-in-the-dashboard) For most applications, the simplest way to create and manage roles and permissions is through the Scalekit dashboard. This approach works well when you have a fixed set of roles and permissions that don’t need to be modified by users in your application. You can set up your authorization model once during application configuration and manage it through the dashboard going forward. ![Scalekit dashboard Roles & Permissions page showing the Manage Roles table with admin, member, and viewer roles and a Default Roles panel](/.netlify/images?url=_astro%2Fdefault-roles.DC1cIuRF.png\&w=3200\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) 1. Navigate to **Dashboard** > **Roles & Permissions** > **Permissions** to create permissions: * Click **Create Permission** and provide: * **Name** - Machine-friendly identifier (e.g., `projects:create`) * **Display Name** - Human-readable label (e.g., “Create Projects”) * **Description** - Clear explanation of what this permission allows 2. Go to **Dashboard** > **Roles & Permissions** > **Roles** to create roles: * Click **Create Role** and provide: * **Name** - Machine-friendly identifier (e.g., `project_manager`) * **Display Name** - Human-readable label (e.g., “Project Manager”) * **Description** - Clear explanation of the role’s purpose * **Permissions** - Select the permissions to include in this role 3. Configure default roles for new users who join organizations 4. Organization administrators can create organization-specific roles by going to **Dashboard** > **Organizations** > **Select organization** > **Roles** Now that you have created roles and permissions in Scalekit, the next step is to assign these roles to users in your application. ### Configure organization specific roles [Section titled “Configure organization specific roles”](#configure-organization-specific-roles) Organization-level roles let organization administrators create custom roles that apply only within their specific organization. These roles are separate from any application-level roles you define. ![Organization Roles tab for a single organization, showing application roles, organization roles, and a default organization role selector](/.netlify/images?url=_astro%2Fadd-organization-role.D9e4-Diz.png\&w=2934\&h=1586\&dpl=6aaa70ad2ea7b40008ad2afd) You can create organization-level roles from the Scalekit Dashboard: * Go to **Organizations → Select an organization → Roles** * In **Organization roles** section, Click **+ Add role** and provide: * **Display name**: Human-readable name (e.g., “Manager”) * **Name (key)**: Machine-friendly identifier (e.g., `manager`) * **Description**: Clear explanation of what users with this role can do --- # DOCUMENT BOUNDARY --- # Implement access control > Verify permissions and roles in your application code to control user access After configuring permissions and roles, the next critical step is implementing access control directly within your application code. This is achieved by carefully examining the roles and permissions embedded in the user’s access token to make authorization decisions. Scalekit conveniently packages these authorization details during the authentication process, providing you with a comprehensive set of data to make precise access control decisions without requiring additional API calls. This section focuses on implementing access control, which naturally follows user authentication. We recommend completing the authentication [quickstart](/authenticate/fsa/quickstart) before diving into these access control implementation details. ## Start by inspecting the access token [Section titled “Start by inspecting the access token”](#start-by-inspecting-the-access-token) When you [exchange the code for a user profile](/authenticate/fsa/complete-login/), Scalekit also adds additional information that help your app determine the access control decisions. * Auth result ```js 1 { 2 user: { 3 email: "john.doe@example.com", 4 emailVerified: true, 5 givenName: "John", 6 name: "John Doe", 7 id: "usr_74599896446906854" 8 }, 9 idToken: "eyJhbGciO..", // Decode for full user details 10 11 accessToken: "eyJhbGciOi..", 12 refreshToken: "rt_8f7d6e5c4b3a2d1e0f9g8h7i6j..", 13 expiresIn: 299 // in seconds 14 } ``` * Decoded ID token ID token decoded ```json 1 { 2 "at_hash": "ec_jU2ZKpFelCKLTRWiRsg", 3 "aud": [ 4 "skc_58327482062864390" 5 ], 6 "azp": "skc_58327482062864390", 7 "c_hash": "6wMreK9kWQQY6O5R0CiiYg", 8 "client_id": "skc_58327482062864390", 9 "email": "john.doe@example.com", 10 "email_verified": true, 11 "exp": 1742975822, 12 "family_name": "Doe", 13 "given_name": "John", 14 "iat": 1742974022, 15 "iss": "https://scalekit-z44iroqaaada-dev.scalekit.cloud", 16 "name": "John Doe", 17 "oid": "org_59615193906282635", 18 "sid": "ses_65274187031249433", 19 "sub": "usr_63261014140912135" 20 } ``` * Decoded access token Decoded access token ```json 1 { 2 "aud": [ 3 "prd_skc_7848964512134X699" 4 ], 5 "client_id": "prd_skc_7848964512134X699", 6 "exp": 1758265247, 7 "iat": 1758264947, 8 "iss": "https://login.devramp.ai", 9 "jti": "tkn_90928731115292X63", 10 "nbf": 1758264947, 11 "oid": "org_89678001X21929734", 12 "permissions": [ 13 "workspace_data:write", 14 "workspace_data:read" 15 ], 16 "roles": [ 17 "admin" 18 ], 19 "sid": "ses_90928729571723X24", 20 "sub": "usr_8967800122X995270", 21 // External identifiers if updated on Scalekit 22 "xoid": "ext_org_123", // Organization ID 23 "xuid": "ext_usr_456", // User ID 24 } ``` Let’s closely look at the access token: Decoded access token ```json { "aud": ["skc_987654321098765432"], "client_id": "skc_987654321098765432", "exp": 1750850145, "iat": 1750849845, "iss": "http://example.localhost:8889", "jti": "tkn_987654321098765432", "nbf": 1750849845, "roles": ["project_manager", "member"], "oid": "org_69615647365005430", "permissions": ["projects:create", "projects:read", "projects:update", "tasks:assign"], "sid": "ses_987654321098765432", "sub": "usr_987654321098765432" } ``` The `roles` and `permissions` values provide runtime insights into the user’s access constraints directly within the access token, eliminating the need for additional API requests. Crucially, always validate the token’s integrity before relying on the embedded authorization details. * Node.js Validate and decode access token in middleware ```javascript 1 // Middleware to validate tokens and extract authorization data 2 const validateAndExtractAuth = async (req, res, next) => { 3 try { 4 // Extract access token from cookie (decrypt if needed) 5 const accessToken = decrypt(req.cookies.accessToken); 6 7 // Validate the token using Scalekit SDK 8 const isValid = await scalekit.validateAccessToken(accessToken); 9 10 if (!isValid) { 11 return res.status(401).json({ error: 'Invalid or expired token' }); 12 } 13 14 // Decode token to get roles and permissions using any JWT decode library 15 const tokenData = await decodeAccessToken(accessToken); 16 17 // Make authorization data available to route handlers 18 req.user = { 19 id: tokenData.sub, 20 organizationId: tokenData.oid, 21 roles: tokenData.roles || [], 22 permissions: tokenData.permissions || [] 23 }; 24 25 next(); 26 } catch (error) { 27 return res.status(401).json({ error: 'Authentication failed' }); 28 } 29 }; ``` * Python Validate and decode access token ```python 1 from scalekit import ScalekitClient 2 from functools import wraps 3 import jwt 4 5 scalekit_client = ScalekitClient(/* your credentials */) 6 7 def validate_and_extract_auth(f): 8 @wraps(f) 9 def decorated_function(*args, **kwargs): 10 try: 11 # Extract access token from cookie (decrypt if needed) 12 access_token = decrypt(request.cookies.get('accessToken')) 13 14 # Validate the token using Scalekit SDK 15 is_valid = scalekit_client.validate_access_token(access_token) 16 17 if not is_valid: 18 return jsonify({'error': 'Invalid or expired token'}), 401 19 20 # Decode token to get roles and permissions 21 token_data = scalekit_client.decode_access_token(access_token) 22 23 # Make authorization data available to route handlers 24 request.user = { 25 'id': token_data.get('sub'), 26 'organization_id': token_data.get('oid'), 27 'roles': token_data.get('roles', []), 28 'permissions': token_data.get('permissions', []) 29 } 30 31 return f(*args, **kwargs) 32 except Exception as e: 33 return jsonify({'error': 'Authentication failed'}), 401 34 35 return decorated_function ``` * Go Validate and decode access token ```go 1 import ( 2 "context" 3 "encoding/json" 4 "net/http" 5 "github.com/scalekit-inc/scalekit-sdk-go" 6 ) 7 8 scalekitClient := scalekit.NewScalekitClient(/* your credentials */) 9 10 func validateAndExtractAuth(next http.HandlerFunc) http.HandlerFunc { 11 return func(w http.ResponseWriter, r *http.Request) { 12 // Extract access token from cookie (decrypt if needed) 13 cookie, err := r.Cookie("accessToken") 14 if err != nil { 15 http.Error(w, `{"error": "No access token provided"}`, http.StatusUnauthorized) 16 return 17 } 18 19 accessToken, err := decrypt(cookie.Value) 20 if err != nil { 21 http.Error(w, `{"error": "Token decryption failed"}`, http.StatusUnauthorized) 22 return 23 } 24 25 // Validate the token using Scalekit SDK 26 isValid, err := scalekitClient.ValidateAccessToken(r.Context(), accessToken) 27 if err != nil || !isValid { 28 http.Error(w, `{"error": "Invalid or expired token"}`, http.StatusUnauthorized) 29 return 30 } 31 32 // Decode token to get roles and permissions using any JWT decode lib 33 tokenData, err := DecodeAccessToken(accessToken) 34 if err != nil { 35 http.Error(w, `{"error": "Token decode failed"}`, http.StatusUnauthorized) 36 return 37 } 38 39 // Add authorization data to request context 40 user := map[string]interface{}{ 41 "id": tokenData["sub"], 42 "organization_id": tokenData["oid"], 43 "roles": tokenData["roles"], 44 "permissions": tokenData["permissions"], 45 } 46 47 ctx := context.WithValue(r.Context(), "user", user) 48 next(w, r.WithContext(ctx)) 49 } 50 } ``` * Java Validate and decode access token ```java 1 import com.scalekit.ScalekitClient; 2 import javax.servlet.http.HttpServletRequest; 3 import javax.servlet.http.HttpServletResponse; 4 import org.springframework.web.servlet.HandlerInterceptor; 5 import java.util.Map; 6 import java.util.HashMap; 7 8 @Component 9 public class AuthorizationInterceptor implements HandlerInterceptor { 10 private final ScalekitClient scalekit; 11 12 @Override 13 public boolean preHandle( 14 HttpServletRequest request, 15 HttpServletResponse response, 16 Object handler 17 ) throws Exception { 18 try { 19 // Extract access token from cookie (decrypt if needed) 20 String accessToken = getCookieValue(request, "accessToken"); 21 String decryptedToken = decrypt(accessToken); 22 23 // Validate the token using Scalekit SDK 24 boolean isValid = scalekit.authentication().validateAccessToken(decryptedToken); 25 26 if (!isValid) { 27 response.setStatus(HttpStatus.UNAUTHORIZED.value()); 28 response.getWriter().write("{\"error\": \"Invalid or expired token\"}"); 29 return false; 30 } 31 32 // Decode token to get roles and permissions using any JWT decode lib 33 Map tokenData = decodeAccessToken(decryptedToken); 34 35 // Make authorization data available to controllers 36 Map user = new HashMap<>(); 37 user.put("id", tokenData.get("sub")); 38 user.put("organizationId", tokenData.get("oid")); 39 user.put("roles", tokenData.get("roles")); 40 user.put("permissions", tokenData.get("permissions")); 41 42 request.setAttribute("user", user); 43 return true; 44 45 } catch (Exception e) { 46 response.setStatus(HttpStatus.UNAUTHORIZED.value()); 47 response.getWriter().write("{\"error\": \"Authentication failed\"}"); 48 return false; 49 } 50 } 51 } ``` This approach makes user roles and permissions available throughout different routes of your application, enabling consistent and secure access control across all endpoints. ## Verify user’s role to allow access to protected resources [Section titled “Verify user’s role to allow access to protected resources”](#verify-users-role-to-allow-access-to-protected-resources) Role-based access control (RBAC) provides a straightforward way to manage permissions by grouping them into logical roles. Instead of checking individual permissions for every action, your application can simply verify if the user has the required role, making access control decisions more efficient and easier to maintain. * Node.js Role-based access control ```javascript 1 // Helper function to check roles 2 function hasRole(user, requiredRole) { 3 return user.roles && user.roles.includes(requiredRole); 4 } 5 6 // Middleware to require specific roles 7 function requireRole(role) { 8 return (req, res, next) => { 9 if (!hasRole(req.user, role)) { 10 return res.status(403).json({ 11 error: `Access denied. Required role: ${role}` 12 }); 13 } 14 next(); 15 }; 16 } 17 18 // Admin-only routes 19 app.get('/api/admin/users', validateAndExtractAuth, requireRole('admin'), (req, res) => { 20 // Only admin users can access this endpoint 21 res.json(getAllUsers(req.user.organizationId)); 22 }); 23 24 // Multiple role check 25 app.post('/api/admin/invite-user', validateAndExtractAuth, (req, res) => { 26 const user = req.user; 27 28 // Allow admins or managers to invite users 29 if (!hasRole(user, 'admin') && !hasRole(user, 'manager')) { 30 return res.status(403).json({ error: 'Only admins and managers can invite users' }); 31 } 32 33 const invitation = createUserInvitation(req.body, user.organizationId); 34 res.json(invitation); 35 }); ``` * Python Role-based access control ```python 1 # Helper function to check roles 2 def has_role(user, required_role): 3 roles = user.get('roles', []) 4 return required_role in roles 5 6 # Decorator to require specific roles 7 def require_role(role): 8 def decorator(f): 9 @wraps(f) 10 def decorated_function(*args, **kwargs): 11 user = getattr(request, 'user', {}) 12 if not has_role(user, role): 13 return jsonify({'error': f'Access denied. Required role: {role}'}), 403 14 return f(*args, **kwargs) 15 return decorated_function 16 return decorator 17 18 # Admin-only routes 19 @app.route('/api/admin/users') 20 @validate_and_extract_auth 21 @require_role('admin') 22 def get_all_users(): 23 # Only admin users can access this endpoint 24 return jsonify(get_all_users_for_org(request.user['organization_id'])) 25 26 # Multiple role check 27 @app.route('/api/admin/invite-user', methods=['POST']) 28 @validate_and_extract_auth 29 def invite_user(): 30 user = request.user 31 32 # Allow admins or managers to invite users 33 if not has_role(user, 'admin') and not has_role(user, 'manager'): 34 return jsonify({'error': 'Only admins and managers can invite users'}), 403 35 36 invitation = create_user_invitation(request.json, user['organization_id']) 37 return jsonify(invitation) ``` * Go Role-based access control ```go 1 // Helper function to check roles 2 func hasRole(user map[string]interface{}, requiredRole string) bool { 3 roles, ok := user["roles"].([]interface{}) 4 if !ok { 5 return false 6 } 7 8 for _, role := range roles { 9 if roleStr, ok := role.(string); ok && roleStr == requiredRole { 10 return true 11 } 12 } 13 return false 14 } 15 16 // Middleware to require specific roles 17 func requireRole(role string) func(http.HandlerFunc) http.HandlerFunc { 18 return func(next http.HandlerFunc) http.HandlerFunc { 19 return func(w http.ResponseWriter, r *http.Request) { 20 user := r.Context().Value("user").(map[string]interface{}) 21 22 if !hasRole(user, role) { 23 http.Error(w, fmt.Sprintf(`{"error": "Access denied. Required role: %s"}`, role), http.StatusForbidden) 24 return 25 } 26 27 next(w, r) 28 } 29 } 30 } 31 32 // Admin-only routes 33 func getAllUsersHandler(w http.ResponseWriter, r *http.Request) { 34 user := r.Context().Value("user").(map[string]interface{}) 35 orgId := user["organization_id"].(string) 36 37 // Only admin users can access this endpoint 38 users := getAllUsersForOrg(orgId) 39 json.NewEncoder(w).Encode(users) 40 } 41 42 // Route setup with role middleware 43 http.HandleFunc("/api/admin/users", validateAndExtractAuth(requireRole("admin")(getAllUsersHandler))) ``` * Java Role-based access control ```java 1 @RestController 2 public class AdminController { 3 4 // Helper method to check roles 5 private boolean hasRole(Map user, String requiredRole) { 6 List roles = (List) user.get("roles"); 7 return roles != null && roles.contains(requiredRole); 8 } 9 10 // Admin-only endpoint 11 @GetMapping("/api/admin/users") 12 public ResponseEntity> getAllUsers(HttpServletRequest request) { 13 Map user = (Map) request.getAttribute("user"); 14 15 // Check for admin role 16 if (!hasRole(user, "admin")) { 17 return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); 18 } 19 20 String orgId = (String) user.get("organizationId"); 21 List users = userService.getAllUsersForOrg(orgId); 22 return ResponseEntity.ok(users); 23 } 24 25 @PostMapping("/api/admin/invite-user") 26 public ResponseEntity inviteUser( 27 @RequestBody InviteUserRequest request, 28 HttpServletRequest httpRequest 29 ) { 30 Map user = (Map) httpRequest.getAttribute("user"); 31 32 // Allow admins or managers to invite users 33 if (!hasRole(user, "admin") && !hasRole(user, "manager")) { 34 return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); 35 } 36 37 String orgId = (String) user.get("organizationId"); 38 Invitation invitation = userService.createInvitation(request, orgId); 39 return ResponseEntity.ok(invitation); 40 } 41 } ``` ## Verify user’s permissions to allow specific actions [Section titled “Verify user’s permissions to allow specific actions”](#verify-users-permissions-to-allow-specific-actions) Permission-based access control provides granular control over specific actions and resources within your application. While roles offer broad access patterns, permissions allow you to define exactly what operations users can perform, enabling precise security controls and the principle of least privilege. * Node.js Permission-based access control ```javascript 1 // Helper function to check permissions 2 function hasPermission(user, requiredPermission) { 3 return user.permissions && user.permissions.includes(requiredPermission); 4 } 5 6 // Middleware to require specific permissions 7 function requirePermission(permission) { 8 return (req, res, next) => { 9 if (!hasPermission(req.user, permission)) { 10 return res.status(403).json({ 11 error: `Access denied. Required permission: ${permission}` 12 }); 13 } 14 next(); 15 }; 16 } 17 18 // Protected routes with permission checks 19 app.get('/api/projects', validateAndExtractAuth, requirePermission('projects:read'), (req, res) => { 20 // User has projects:read permission - allow access 21 res.json(getProjects(req.user.organizationId)); 22 }); 23 24 app.post('/api/projects', validateAndExtractAuth, requirePermission('projects:create'), (req, res) => { 25 // User has projects:create permission - allow creation 26 const newProject = createProject(req.body, req.user.organizationId); 27 res.json(newProject); 28 }); 29 30 // Multiple permission check 31 app.delete('/api/projects/:id', validateAndExtractAuth, (req, res) => { 32 const user = req.user; 33 34 // Check if user has either admin role or specific delete permission 35 if (!hasPermission(user, 'projects:delete') && !user.roles.includes('admin')) { 36 return res.status(403).json({ error: 'Cannot delete projects' }); 37 } 38 39 deleteProject(req.params.id, user.organizationId); 40 res.json({ success: true }); 41 }); ``` * Python Permission-based access control ```python 1 # Helper function to check permissions 2 def has_permission(user, required_permission): 3 permissions = user.get('permissions', []) 4 return required_permission in permissions 5 6 # Decorator to require specific permissions 7 def require_permission(permission): 8 def decorator(f): 9 @wraps(f) 10 def decorated_function(*args, **kwargs): 11 user = getattr(request, 'user', {}) 12 if not has_permission(user, permission): 13 return jsonify({'error': f'Access denied. Required permission: {permission}'}), 403 14 return f(*args, **kwargs) 15 return decorated_function 16 return decorator 17 18 # Protected routes with permission checks 19 @app.route('/api/projects') 20 @validate_and_extract_auth 21 @require_permission('projects:read') 22 def get_projects(): 23 # User has projects:read permission - allow access 24 return jsonify(get_projects_for_org(request.user['organization_id'])) 25 26 @app.route('/api/projects', methods=['POST']) 27 @validate_and_extract_auth 28 @require_permission('projects:create') 29 def create_project(): 30 # User has projects:create permission - allow creation 31 new_project = create_project_for_org(request.json, request.user['organization_id']) 32 return jsonify(new_project) 33 34 # Multiple permission check 35 @app.route('/api/projects/', methods=['DELETE']) 36 @validate_and_extract_auth 37 def delete_project(project_id): 38 user = request.user 39 40 # Check if user has either admin role or specific delete permission 41 if not has_permission(user, 'projects:delete') and 'admin' not in user.get('roles', []): 42 return jsonify({'error': 'Cannot delete projects'}), 403 43 44 delete_project_from_org(project_id, user['organization_id']) 45 return jsonify({'success': True}) ``` * Go Permission-based access control ```go 1 // Helper function to check permissions 2 func hasPermission(user map[string]interface{}, requiredPermission string) bool { 3 permissions, ok := user["permissions"].([]interface{}) 4 if !ok { 5 return false 6 } 7 8 for _, perm := range permissions { 9 if permStr, ok := perm.(string); ok && permStr == requiredPermission { 10 return true 11 } 12 } 13 return false 14 } 15 16 // Middleware to require specific permissions 17 func requirePermission(permission string) func(http.HandlerFunc) http.HandlerFunc { 18 return func(next http.HandlerFunc) http.HandlerFunc { 19 return func(w http.ResponseWriter, r *http.Request) { 20 user := r.Context().Value("user").(map[string]interface{}) 21 22 if !hasPermission(user, permission) { 23 http.Error(w, fmt.Sprintf(`{"error": "Access denied. Required permission: %s"}`, permission), http.StatusForbidden) 24 return 25 } 26 27 next(w, r) 28 } 29 } 30 } 31 32 // Protected routes with permission checks 33 func getProjectsHandler(w http.ResponseWriter, r *http.Request) { 34 user := r.Context().Value("user").(map[string]interface{}) 35 orgId := user["organization_id"].(string) 36 37 // User has projects:read permission - allow access 38 projects := getProjectsForOrg(orgId) 39 json.NewEncoder(w).Encode(projects) 40 } 41 42 func createProjectHandler(w http.ResponseWriter, r *http.Request) { 43 user := r.Context().Value("user").(map[string]interface{}) 44 orgId := user["organization_id"].(string) 45 46 // User has projects:create permission - allow creation 47 var projectData map[string]interface{} 48 json.NewDecoder(r.Body).Decode(&projectData) 49 50 newProject := createProjectForOrg(projectData, orgId) 51 json.NewEncoder(w).Encode(newProject) 52 } 53 54 // Route setup with middleware 55 http.HandleFunc("/api/projects", validateAndExtractAuth(requirePermission("projects:read")(getProjectsHandler))) 56 http.HandleFunc("/api/projects/create", validateAndExtractAuth(requirePermission("projects:create")(createProjectHandler))) ``` * Java Permission-based access control ```java 1 @RestController 2 public class ProjectController { 3 4 // Helper method to check permissions 5 private boolean hasPermission(Map user, String requiredPermission) { 6 List permissions = (List) user.get("permissions"); 7 return permissions != null && permissions.contains(requiredPermission); 8 } 9 10 // Annotation-based permission checking 11 @GetMapping("/api/projects") 12 @PreAuthorize("hasPermission('projects:read')") 13 public ResponseEntity> getProjects(HttpServletRequest request) { 14 Map user = (Map) request.getAttribute("user"); 15 String orgId = (String) user.get("organizationId"); 16 17 // User has projects:read permission - allow access 18 List projects = projectService.getProjectsForOrg(orgId); 19 return ResponseEntity.ok(projects); 20 } 21 22 @PostMapping("/api/projects") 23 public ResponseEntity createProject( 24 @RequestBody CreateProjectRequest request, 25 HttpServletRequest httpRequest 26 ) { 27 Map user = (Map) httpRequest.getAttribute("user"); 28 29 // Check permission manually 30 if (!hasPermission(user, "projects:create")) { 31 return ResponseEntity.status(HttpStatus.FORBIDDEN) 32 .body(null); 33 } 34 35 String orgId = (String) user.get("organizationId"); 36 Project newProject = projectService.createProject(request, orgId); 37 return ResponseEntity.ok(newProject); 38 } 39 40 @DeleteMapping("/api/projects/{projectId}") 41 public ResponseEntity> deleteProject( 42 @PathVariable String projectId, 43 HttpServletRequest request 44 ) { 45 Map user = (Map) request.getAttribute("user"); 46 List roles = (List) user.get("roles"); 47 48 // Check if user has either admin role or specific delete permission 49 if (!hasPermission(user, "projects:delete") && !roles.contains("admin")) { 50 return ResponseEntity.status(HttpStatus.FORBIDDEN) 51 .body(Map.of("error", true)); 52 } 53 54 String orgId = (String) user.get("organizationId"); 55 projectService.deleteProject(projectId, orgId); 56 return ResponseEntity.ok(Map.of("success", true)); 57 } 58 } ``` By implementing both role-based and permission-based access control, your application now has a comprehensive security framework that protects different routes and endpoints. You can combine both approaches to create fine-grained access control that matches your application’s specific requirements. **Admin bypass pattern**: Allow users with `admin` role to bypass certain permission checks while maintaining granular control for other users **Resource ownership pattern**: Combine role/permission checks with resource ownership verification (e.g., users can only edit their own projects unless they have admin role) **Time-based access pattern**: Consider implementing time-based restrictions for sensitive operations, especially for roles with elevated permissions Caution Never implement authorization logic solely on the client side. Always perform server-side validation of roles and permissions, as client-side checks can be bypassed by malicious users. --- # DOCUMENT BOUNDARY --- # Manage encryption keys > Protect data at rest with Scalekit managed keys or bring your own from a cloud Key Management Service (KMS). Scalekit automatically protects data at rest with encryption keys. You can use Scalekit-managed keys or bring your own from a cloud Key Management Service (KMS) provider if your compliance policy requires you to own and control the root key. This guide shows you how to view and manage keys in the dashboard and set up Bring Your Own Key (BYOK) with GCP Cloud KMS. ## Key types | Type | Description | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- | | **Scalekit managed Data Encryption Key (DEK)** | Scalekit generates and manages the key. No setup required. | | **Bring your own key (BYOK)** | You provide a key from your own KMS. You own the key lifecycle, including rotation and revocation. | ## Key states | State | Description | | ---------- | ----------------------------------------------------------------------------------------------- | | Staged | Created, not yet in use. No data is encrypted with it. | | Primary | The active key. All new encryption operations use it. | | Deprecated | Replaced by a newer key. Existing records may still reference it until re-encryption completes. | ## Manage keys Go to **Settings** and open the **Encryption keys** tab. 1. **Create a key** Click **Create New Key** and select a provider: * **Scalekit Managed DEK**: Scalekit generates and manages the key. Click **Create**. * **BYOK - GCP Cloud KMS**: Complete [Set up BYOK with GCP KMS](#set-up-byok-with-gcp-kms) first to create the GCP key and grant access, then enter the key resource name here and click **Create**. The key is created in **Staged** state. 2. **Activate the key** Click **Activate** on a Staged key. The key becomes Primary and Scalekit uses it for all new encryption operations. 3. **Re-encrypt existing data** To apply the new key to existing records, click **Re-encrypt Data**. Scalekit decrypts each existing record with the previous key and re-encrypts it with the new key. ## Set up BYOK with GCP KMS Use BYOK to register an encryption key from Google Cloud KMS that your team owns and controls. Scalekit uses the KMS API for all encrypt and decrypt operations and never stores the key material. You own the key lifecycle BYOK gives you direct control over your encryption key. Scalekit cannot rotate or manage the GCP key on your behalf. If the key is disabled, destroyed, or Identity and Access Management (IAM) access is revoked, Scalekit cannot encrypt new data or decrypt existing records until you restore access. ### Prerequisites * A **Google Cloud project** with the [Cloud KMS API enabled](https://cloud.google.com/kms/docs/create-encryption-keys) * **IAM permissions** to create key rings, keys, and set key-level IAM policies * The **Scalekit service account email**, shown in the Scalekit dashboard when you select BYOK * `gcloud` CLI installed and authenticated, or access to the [GCP Console](https://console.cloud.google.com/security/kms) 1. **Create a key ring** A [key ring](https://cloud.google.com/kms/docs/resource-hierarchy#key_rings) groups encryption keys by location. Key rings cannot be deleted or renamed once created. Choose the name and location carefully. * gcloud CLI ```bash 1 gcloud kms keyrings create "scalekit-kms-keyring" \ 2 --location "global" \ 3 --project "YOUR-GCP-PROJECT" ``` Replace `YOUR-GCP-PROJECT` with your Google Cloud project ID. * GCP Console 1. Open [**Security > Key management**](https://console.cloud.google.com/security/kms), click **Key rings**. 2. Click **Create key ring**, enter `scalekit-kms-keyring` as the name. 3. Set **Location** to **Global** and click **Create**. 2. **Create an encryption key** Create a symmetric AES-256-GCM key inside the key ring. * gcloud CLI ```bash 1 gcloud kms keys create "scalekit-kms-key" \ 2 --location "global" \ 3 --keyring "scalekit-kms-keyring" \ 4 --purpose "encryption" \ 5 --project "YOUR-GCP-PROJECT" ``` * GCP Console 1. Click the key ring you created, then click **Create key**. 2. Enter `scalekit-kms-key` as the name. 3. Set **Protection level** to **HSM** (recommended) and click **Continue**. 4. Set **Key material** to **HSM-generated** and click **Continue**. 5. Set **Purpose** to **Symmetric encrypt/decrypt** and click **Continue**. 6. Set **Rotation period** per your policy and click **Create**. 3. **Grant Scalekit access to the key** Grant both roles at the key level to limit Scalekit’s IAM access to this specific key. | Role | Purpose | | -------------------------------------------- | ----------------------------------------------- | | `roles/cloudkms.cryptoKeyEncrypterDecrypter` | Encrypt and decrypt the DEK | | `roles/cloudkms.viewer` | Read key metadata for health checks and listing | * gcloud CLI ```bash 1 gcloud kms keys add-iam-policy-binding "scalekit-kms-key" \ 2 --keyring "scalekit-kms-keyring" \ 3 --location "global" \ 4 --project "YOUR-GCP-PROJECT" \ 5 --member "serviceAccount:SCALEKIT-SERVICE-ACCOUNT" \ 6 --role "roles/cloudkms.cryptoKeyEncrypterDecrypter" 7 8 gcloud kms keys add-iam-policy-binding "scalekit-kms-key" \ 9 --keyring "scalekit-kms-keyring" \ 10 --location "global" \ 11 --project "YOUR-GCP-PROJECT" \ 12 --member "serviceAccount:SCALEKIT-SERVICE-ACCOUNT" \ 13 --role "roles/cloudkms.viewer" ``` * GCP Console 1. In the GCP Console, open **Security > Key management**, click **Key rings**, then click the key ring name. 2. Click the key name, then open the **Permissions** tab. 3. Click **Grant access**. A side panel opens. 4. In the **New principals** field, enter the Scalekit service account email. Copy it from **Settings > Encryption keys > Create New Key > BYOK - GCP Cloud KMS** in the Scalekit dashboard. 5. In the **Assign Roles** section, select **Cloud KMS CryptoKey Encrypter/Decrypter** from the first **Role** dropdown. 6. Click **+ Add another role** and select **Cloud KMS Viewer**. 7. Click **Save**. The policy update takes effect within a few minutes. 4. **Register the key in Scalekit** * In the Scalekit dashboard, go to **Settings** and open the **Encryption keys** tab. * Click **Create New Key** and select **BYOK - GCP Cloud KMS**. * Copy the Scalekit service account email shown in the modal. You need it for step 3 (grant Scalekit access to the key) if you have not granted IAM access yet. * Enter the fully-qualified GCP key resource name: ```plaintext 1 projects/YOUR-GCP-PROJECT/locations/global/keyRings/scalekit-kms-keyring/cryptoKeys/scalekit-kms-key ``` To retrieve the exact name from the CLI: ```bash 1 gcloud kms keys describe "scalekit-kms-key" \ 2 --keyring "scalekit-kms-keyring" \ 3 --location "global" \ 4 --project "YOUR-GCP-PROJECT" \ 5 --format="value(name)" ``` * Click **Create**. The key is created in **Staged** state. 5. **Activate the key** Click **Activate** on the staged key. The key becomes Primary and Scalekit uses it for all new encryption operations. Activation is permanent Once activated, you cannot deactivate the key without creating and activating a new key. Confirm your IAM grants are in place before activating. 6. **Re-encrypt existing data** Activation covers new writes automatically. Click **Re-encrypt Data** to migrate existing records. Scalekit decrypts each record with the previous key and re-encrypts it with the new key. ## Monitor with audit logs Cloud KMS logs every cryptographic operation to [Cloud Audit Logs](https://cloud.google.com/kms/docs/audit-logging). Use this filter in **Cloud Logging** to see all encrypt, decrypt, and key events for your key: ```plaintext 1 resource.type="cloudkms_cryptokey" ``` ## Fix common errors --- # DOCUMENT BOUNDARY --- # SaaSKit code samples > Full stack auth code samples demonstrating complete authentication implementations with hosted login and session management ### [Full Stack Auth with Next.js](https://github.com/scalekit-inc/scalekit-nextjs-auth-example) [Complete authentication solution for Next.js apps. Includes hosted login pages, session management, and protected routes](https://github.com/scalekit-inc/scalekit-nextjs-auth-example) ### [Full Stack Auth with FastAPI](https://github.com/scalekit-inc/scalekit-fastapi-auth-example) [Authentication template for FastAPI projects. Featuring integrated user sessions, hosted login flow, and ready-to-use route protection specifically tailored for Python web backends.](https://github.com/scalekit-inc/scalekit-fastapi-auth-example) ### [Full Stack Auth with Flask](https://github.com/scalekit-inc/scalekit-flask-auth-example) [Authentication template for Flask applications. Features session management, hosted login flow, and decorator-based route protection](https://github.com/scalekit-inc/scalekit-flask-auth-example) ### [Full Stack Auth with Django](https://github.com/scalekit-inc/scalekit-django-auth-example) [Authentication template for Django projects. Features session management, hosted login flow, and middleware-based route protection](https://github.com/scalekit-inc/scalekit-django-auth-example) ### [Full Stack Auth with Express](https://github.com/scalekit-inc/scalekit-express-auth-example) [Complete authentication solution for Express.js applications. Includes hosted login pages, session management, and middleware-protected routes](https://github.com/scalekit-inc/scalekit-express-auth-example) ### [Full Stack Auth with Spring Boot](https://github.com/scalekit-inc/scalekit-springboot-auth-example) [End-to-end authentication for Java applications. Features Spring Security integration, hosted login, and session handling](https://github.com/scalekit-inc/scalekit-springboot-auth-example) ### [Full Stack Auth with Laravel](https://github.com/scalekit-inc/scalekit-laravel-auth-example) [Complete authentication solution for Laravel applications. Includes hosted login pages, session management, and middleware-protected routes](https://github.com/scalekit-inc/scalekit-laravel-auth-example) ### End to end full stack auth demo Coffee Desk App Complete coffee shop management application with full stack. Features workspaces, organization switcher, and mulitple auth methods [View demo](https://dashboard.coffeedesk.app/) | [View code](https://github.com/scalekit-inc/coffee-desk-demo) --- # DOCUMENT BOUNDARY --- # Implement logout > Terminate user sessions across your application and Scalekit When implementing logout functionality, you need to consider three session layers where user authentication state is maintained: 1. **Application session layer**: Your application stores session tokens (access tokens, refresh tokens, ID tokens) in browser cookies. You control this layer completely. 2. **Scalekit session layer**: Scalekit maintains a session for the user and stores their information. When users return to Scalekit’s authentication page, their information is remembered for a smoother experience. 3. **Identity provider session layer**: When users authenticate with external providers (for example, Okta through enterprise SSO), those providers maintain their own sessions. Users won’t be prompted to sign in again if they’re already signed into the provider. Clear the application session layer and invalidate the Scalekit session layer in a single logout endpoint. ![Logout flow showing three session layers](/.netlify/images?url=_astro%2F1.DR4kQkNT.png\&w=4056\&h=2344\&dpl=6aaa70ad2ea7b40008ad2afd) 1. ## Create a logout endpoint [Section titled “Create a logout endpoint”](#create-a-logout-endpoint) Create a `/logout` endpoint in your application that handles the complete logout flow: extracting the ID token, generating the Scalekit logout URL, clearing session cookies, and redirecting to Scalekit. * Node.js * Express ```html 1 Log out ``` `auth.router` already registered `GET /logout`. * Next.js app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` ```html 1 Log out ``` * Python ```html 1 Log out ``` `auth.router` already registered `GET /logout`. * Go app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` ```html 1 Log out ``` * Java * Flask ```html 1 Log out ``` `ScalekitAuth` already registered `GET /logout`. * FastAPI ```html 1 Log out ``` `auth.install(app)` already registered `GET /logout`. * Express ```html 1 Log out ``` `ScalekitAuth` already registered `GET /logout`. * Next.js ```html 1 Log out ``` `auth.install(app)` already registered `GET /logout`. * Flask Gin ```go 1 func logoutHandler(c *gin.Context) { 2 // Step 1: Extract the ID token (needed for Scalekit logout) 3 idToken, _ := c.Cookie("idToken") 4 postLogoutRedirectURI := "http://localhost:3000/login" 5 6 // Step 2: Generate the Scalekit logout URL (points to /oidc/logout endpoint) 7 logoutURL, err := scalekitClient.GetLogoutUrl(LogoutUrlOptions{ 8 IdTokenHint: idToken, 9 PostLogoutRedirectUri: postLogoutRedirectURI, 10 }) 11 if err != nil { 12 c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 13 return 14 } 15 16 // Step 3: Clear all session cookies 17 c.SetCookie("accessToken", "", -1, "/", "", true, true) 18 c.SetCookie("refreshToken", "", -1, "/", "", true, true) 19 c.SetCookie("idToken", "", -1, "/", "", true, true) // Clear AFTER using it for logout URL 20 21 // Step 4: Redirect to Scalekit to invalidate the session 22 c.Redirect(http.StatusFound, logoutURL.String()) 23 } ``` * FastAPI Spring Boot ```java 1 @GetMapping("/logout") 2 public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException { 3 // Step 1: Extract the ID token (needed for Scalekit logout) 4 String idToken = request.getCookies() != null ? 5 Arrays.stream(request.getCookies()) 6 .filter(c -> c.getName().equals("idToken")) 7 .findFirst() 8 .map(Cookie::getValue) 9 .orElse(null) : null; 10 11 String postLogoutRedirectUri = "http://localhost:3000/login"; 12 13 // Step 2: Generate the Scalekit logout URL (points to /oidc/logout endpoint) 14 LogoutUrlOptions options = new LogoutUrlOptions(); 15 options.setIdTokenHint(idToken); 16 options.setPostLogoutRedirectUri(postLogoutRedirectUri); 17 URL logoutUrl = scalekitClient.authentication().getLogoutUrl(options); 18 19 // Step 3: Clear all session cookies with security attributes 20 Cookie accessTokenCookie = new Cookie("accessToken", null); 21 accessTokenCookie.setMaxAge(0); 22 accessTokenCookie.setPath("/"); 23 accessTokenCookie.setHttpOnly(true); 24 accessTokenCookie.setSecure(true); 25 response.addCookie(accessTokenCookie); 26 27 Cookie refreshTokenCookie = new Cookie("refreshToken", null); 28 refreshTokenCookie.setMaxAge(0); 29 refreshTokenCookie.setPath("/"); 30 refreshTokenCookie.setHttpOnly(true); 31 refreshTokenCookie.setSecure(true); 32 response.addCookie(refreshTokenCookie); 33 34 Cookie idTokenCookie = new Cookie("idToken", null); 35 idTokenCookie.setMaxAge(0); 36 idTokenCookie.setPath("/"); 37 idTokenCookie.setHttpOnly(true); 38 idTokenCookie.setSecure(true); 39 response.addCookie(idTokenCookie); // Clear AFTER using it for logout URL 40 41 // Step 4: Redirect to Scalekit to invalidate the session 42 response.sendRedirect(logoutUrl.toString()); 43 } ``` Session middleware clears `sk_session` and ends the Scalekit session. If you build logout yourself, extract the ID token before you clear cookies. 2. ## Configure post-logout redirect URL [Section titled “Configure post-logout redirect URL”](#configure-post-logout-redirect-url) After users log out, Scalekit redirects them to the URL you specify in the `post_logout_redirect_uri` parameter. This URL must be registered in your Scalekit dashboard under **Dashboard > Authentication > Redirects > Post Logout URL**. Scalekit only redirects to URLs from your allow list. This prevents unauthorized redirects and protects your users. If you need different redirect URLs for different applications, you can register multiple post-logout URLs in your dashboard. ## Common logout scenarios [Section titled “Common logout scenarios”](#common-logout-scenarios) --- # DOCUMENT BOUNDARY --- # Manage user sessions > Store tokens safely with proper cookie security, validate on every request, and refresh with rotation to keep sessions secure User sessions determine how long users stay signed in to your application. After users successfully authenticate, you receive session tokens that manage their access. These tokens control session duration, multi-device access, and cross-product authentication within your company’s ecosystem. Store those tokens securely, validate them on every request, and refresh them before they expire. Session middleware writes one encrypted `sk_session` cookie and does that work for you. You can still store and refresh tokens yourself if you prefer. 1. ## Store the session [Section titled “Store the session”](#store-the-session) After hosted login, session middleware writes one encrypted `sk_session` cookie. You do not set `accessToken` or `refreshToken` cookies. Add `COOKIE_ENCRYPTION_SECRET` to `.env`. Generate it with `openssl rand -base64 32`. Use the same value on every server. * Node.js * Express Install `@scalekit-sdk/node` 2.12.0 or later. Mount `auth.router`. It registers `/login`, `/callback`, and `/logout`. The callback writes `sk_session`. server.ts ```ts 1 import express from 'express'; 2 import { ScalekitAuth } from '@scalekit-sdk/node/express'; 3 4 const auth = new ScalekitAuth({ 5 envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, 6 clientId: process.env.SCALEKIT_CLIENT_ID, 7 clientSecret: process.env.SCALEKIT_CLIENT_SECRET, 8 redirectUri: process.env.REDIRECT_URI, 9 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET, 10 }); 11 12 const app = express(); 13 app.use(auth.router); ``` * Next.js Install `@scalekit-sdk/node` 2.12.0 or later. Create one `auth` instance. Export login, callback, and logout Route Handlers. The callback writes `sk_session`. lib/auth.ts ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ScalekitAuthNext } from '@scalekit-sdk/node/next'; 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENVIRONMENT_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET! 8 ); 9 10 export const auth = new ScalekitAuthNext({ 11 client: scalekit, 12 redirectUri: process.env.REDIRECT_URI!, 13 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET!, 14 }); ``` app/login/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLoginHandler(); ``` app/callback/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createCallbackHandler(); ``` app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` Pin `runtime: 'nodejs'` in `middleware.ts`, or pass [ScalekitEdgeClient](/saaskit/sdks/nextjs/#scalekitedgeclient) for Edge Runtime. * Python Install `@scalekit-sdk/node` 2.12.0 or later. Mount `auth.router`. It registers `/login`, `/callback`, and `/logout`. The callback writes `sk_session`. server.ts ```ts 1 import express from 'express'; 2 import { ScalekitAuth } from '@scalekit-sdk/node/express'; 3 4 const auth = new ScalekitAuth({ 5 envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, 6 clientId: process.env.SCALEKIT_CLIENT_ID, 7 clientSecret: process.env.SCALEKIT_CLIENT_SECRET, 8 redirectUri: process.env.REDIRECT_URI, 9 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET, 10 }); 11 12 const app = express(); 13 app.use(auth.router); ``` * Go Install `@scalekit-sdk/node` 2.12.0 or later. Create one `auth` instance. Export login, callback, and logout Route Handlers. The callback writes `sk_session`. lib/auth.ts ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import { ScalekitAuthNext } from '@scalekit-sdk/node/next'; 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENVIRONMENT_URL!, 6 process.env.SCALEKIT_CLIENT_ID!, 7 process.env.SCALEKIT_CLIENT_SECRET! 8 ); 9 10 export const auth = new ScalekitAuthNext({ 11 client: scalekit, 12 redirectUri: process.env.REDIRECT_URI!, 13 cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET!, 14 }); ``` app/login/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLoginHandler(); ``` app/callback/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createCallbackHandler(); ``` app/logout/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 export const GET = auth.createLogoutHandler(); ``` Pin `runtime: 'nodejs'` in `middleware.ts`, or pass [ScalekitEdgeClient](/saaskit/sdks/nextjs/#scalekitedgeclient) for Edge Runtime. * Java * Flask Install `scalekit-sdk-python` 2.17.0 or later with the Flask extra. `ScalekitAuth` registers `/login`, `/callback`, and `/logout` and writes `sk_session`. app.py ```py 1 import os 2 from flask import Flask 3 from scalekit.frameworks.flask import ScalekitAuth 4 5 app = Flask(__name__) 6 auth = ScalekitAuth( 7 app, 8 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 9 client_id=os.environ["SCALEKIT_CLIENT_ID"], 10 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 11 redirect_uri=os.environ["REDIRECT_URI"], 12 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 13 # HTTP localhost drops a Secure cookie, so the session never sticks. 14 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 15 cookie_secure=False, 16 ) ``` * FastAPI Install `scalekit-sdk-python` 2.17.0 or later with the FastAPI extra. Call `auth.install(app)` to register routes and write `sk_session`. app.py ```py 1 import os 2 from fastapi import FastAPI 3 from scalekit.frameworks.fastapi import ScalekitAuth 4 5 app = FastAPI() 6 auth = ScalekitAuth( 7 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 8 client_id=os.environ["SCALEKIT_CLIENT_ID"], 9 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 10 redirect_uri=os.environ["REDIRECT_URI"], 11 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 12 # HTTP localhost drops a Secure cookie, so the session never sticks. 13 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 14 cookie_secure=False, 15 ) 16 auth.install(app) ``` Set cookie\_secure=False on local HTTP `cookie_secure` defaults to `True`. Some browsers drop a `Secure` cookie on plain `http://localhost`, which looks like a session that never sticks. Set `cookie_secure=False` for local HTTP. Set it `True` in production. * Express Install `scalekit-sdk-python` 2.17.0 or later with the Flask extra. `ScalekitAuth` registers `/login`, `/callback`, and `/logout` and writes `sk_session`. app.py ```py 1 import os 2 from flask import Flask 3 from scalekit.frameworks.flask import ScalekitAuth 4 5 app = Flask(__name__) 6 auth = ScalekitAuth( 7 app, 8 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 9 client_id=os.environ["SCALEKIT_CLIENT_ID"], 10 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 11 redirect_uri=os.environ["REDIRECT_URI"], 12 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 13 # HTTP localhost drops a Secure cookie, so the session never sticks. 14 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 15 cookie_secure=False, 16 ) ``` * Next.js Install `scalekit-sdk-python` 2.17.0 or later with the FastAPI extra. Call `auth.install(app)` to register routes and write `sk_session`. app.py ```py 1 import os 2 from fastapi import FastAPI 3 from scalekit.frameworks.fastapi import ScalekitAuth 4 5 app = FastAPI() 6 auth = ScalekitAuth( 7 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 8 client_id=os.environ["SCALEKIT_CLIENT_ID"], 9 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 10 redirect_uri=os.environ["REDIRECT_URI"], 11 cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], 12 # HTTP localhost drops a Secure cookie, so the session never sticks. 13 # A missing Secure flag on real HTTP lets the browser send sk_session in cleartext. 14 cookie_secure=False, 15 ) 16 auth.install(app) ``` * Flask Gin ```go 1 import ( 2 "net/http" 3 "os" 4 "time" 5 "github.com/gin-gonic/gin" 6 ) 7 8 // Extract authentication data from the successful authentication response 9 accessToken := authResult.AccessToken 10 expiresIn := authResult.ExpiresIn 11 refreshToken := authResult.RefreshToken 12 user := authResult.User 13 14 // Encrypt tokens before storing to add an additional security layer 15 encryptedAccessToken := encrypt(accessToken) 16 encryptedRefreshToken := encrypt(refreshToken) 17 18 // Set SameSite mode for CSRF protection 19 c.SetSameSite(http.SameSiteStrictMode) // Prevents CSRF attacks 20 21 // Store encrypted access token in HttpOnly cookie 22 c.SetCookie( 23 "accessToken", 24 encryptedAccessToken, 25 expiresIn-60, // Subtract 60s buffer for clock skew (seconds in Gin) 26 "/", // Available on all routes 27 "", 28 os.Getenv("GIN_MODE") == "release", // HTTPS-only in production 29 true, // Prevents JavaScript access to mitigate XSS attacks 30 ) 31 32 // Store encrypted refresh token in separate HttpOnly cookie 33 c.SetCookie( 34 "refreshToken", 35 encryptedRefreshToken, 36 0, // No expiry for refresh token cookie (session lifetime controlled server-side) 37 "/", // Available on all routes 38 "", 39 os.Getenv("GIN_MODE") == "release", // HTTPS-only in production 40 true, // Prevents JavaScript access to mitigate XSS attacks 41 ) ``` * FastAPI Spring ```java 1 import javax.servlet.http.Cookie; 2 import javax.servlet.http.HttpServletResponse; 3 import org.springframework.core.env.Environment; 4 @Autowired 5 private Environment env; 6 7 // Extract authentication data from the successful authentication response 8 String accessToken = authResult.getAccessToken(); 9 int expiresIn = authResult.getExpiresIn(); 10 String refreshToken = authResult.getRefreshToken(); 11 User user = authResult.getUser(); 12 13 // Encrypt tokens before storing to add an additional security layer 14 String encryptedAccessToken = encrypt(accessToken); 15 String encryptedRefreshToken = encrypt(refreshToken); 16 17 // Store encrypted access token in HttpOnly cookie 18 Cookie accessTokenCookie = new Cookie("accessToken", encryptedAccessToken); 19 accessTokenCookie.setMaxAge(expiresIn - 60); // Subtract 60s buffer for clock skew (seconds in Spring) 20 accessTokenCookie.setHttpOnly(true); // Prevents JavaScript access to mitigate XSS attacks 21 accessTokenCookie.setSecure("production".equals(env.getActiveProfiles()[0])); // HTTPS-only in production 22 accessTokenCookie.setPath("/"); // Available on all routes 23 response.addCookie(accessTokenCookie); 24 response.setHeader("Set-Cookie", 25 response.getHeader("Set-Cookie") + "; SameSite=Strict"); // Prevents CSRF attacks 26 27 // Store encrypted refresh token in separate HttpOnly cookie 28 Cookie refreshTokenCookie = new Cookie("refreshToken", encryptedRefreshToken); 29 refreshTokenCookie.setHttpOnly(true); // Prevents JavaScript access to mitigate XSS attacks 30 refreshTokenCookie.setSecure("production".equals(env.getActiveProfiles()[0])); // HTTPS-only in production 31 refreshTokenCookie.setPath("/"); // Available on all routes 32 response.addCookie(refreshTokenCookie); ``` 2. ## Check the session before handling requests [Section titled “Check the session before handling requests”](#check-the-session-before-handling-requests) Session middleware refreshes `sk_session` and redirects to `/login` when the session is missing. A missing session returns **302**, not JSON **401**. * Node.js * Express Guard a route with `auth.requiresAuth`. On success, `req.scalekitUser` is access-token claims. `sub` is always present. server.ts ```ts 1 app.get('/account', auth.requiresAuth, (req, res) => { 2 res.json({ sub: req.scalekitUser?.sub }); 3 }); ``` * Next.js Wrap a Route Handler with `withAuth`. Use `createMiddleware()` so every other path fails closed. List public paths in `publicRoutes`. app/account/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 3 export const GET = auth.withAuth(async (request, { user }) => { 4 return Response.json({ sub: user?.sub }); 5 }); ``` middleware.ts ```ts 1 import { auth } from './lib/auth'; 2 3 export default auth.createMiddleware({ 4 publicRoutes: ['/', '/pricing'], 5 }); 6 7 export const config = { 8 runtime: 'nodejs', 9 matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], 10 }; ``` * Python Guard a route with `auth.requiresAuth`. On success, `req.scalekitUser` is access-token claims. `sub` is always present. server.ts ```ts 1 app.get('/account', auth.requiresAuth, (req, res) => { 2 res.json({ sub: req.scalekitUser?.sub }); 3 }); ``` * Go Wrap a Route Handler with `withAuth`. Use `createMiddleware()` so every other path fails closed. List public paths in `publicRoutes`. app/account/route.ts ```ts 1 import { auth } from '../../lib/auth'; 2 3 export const GET = auth.withAuth(async (request, { user }) => { 4 return Response.json({ sub: user?.sub }); 5 }); ``` middleware.ts ```ts 1 import { auth } from './lib/auth'; 2 3 export default auth.createMiddleware({ 4 publicRoutes: ['/', '/pricing'], 5 }); 6 7 export const config = { 8 runtime: 'nodejs', 9 matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], 10 }; ``` * Java * Flask Guard a view with `@auth.requires_auth`. `auth.current_user` is access-token claims. app.py ```py 1 @app.route("/account") 2 @auth.requires_auth 3 def account(): 4 return {"sub": auth.current_user["sub"]} ``` * FastAPI Protect a route with `Depends(auth.requires_auth)`. The dependency is the user claims. app.py ```py 1 from fastapi import Depends 2 3 @app.get("/account") 4 async def account(user: dict = Depends(auth.requires_auth)): 5 return {"sub": user["sub"]} ``` * Express Guard a view with `@auth.requires_auth`. `auth.current_user` is access-token claims. app.py ```py 1 @app.route("/account") 2 @auth.requires_auth 3 def account(): 4 return {"sub": auth.current_user["sub"]} ``` * Next.js Protect a route with `Depends(auth.requires_auth)`. The dependency is the user claims. app.py ```py 1 from fastapi import Depends 2 3 @app.get("/account") 4 async def account(user: dict = Depends(auth.requires_auth)): 5 return {"sub": user["sub"]} ``` * Flask middleware/auth.go ```go 1 import ( 2 "net/http" 3 "os" 4 "github.com/gin-gonic/gin" 5 ) 6 func VerifyToken() gin.HandlerFunc { 7 return func(c *gin.Context) { 8 // Extract encrypted tokens from request cookies 9 accessToken, err := c.Cookie("accessToken") 10 if err != nil || accessToken == "" { 11 c.JSON(http.StatusUnauthorized, gin.H{"error": "Authentication required"}) 12 c.Abort() 13 return 14 } 15 16 // Decrypt the access token before validation 17 decryptedAccessToken := decrypt(accessToken) 18 19 // Verify token validity using Scalekit's validation method 20 isValid, err := scalekitClient.ValidateAccessToken(c.Request.Context(), decryptedAccessToken) 21 22 if (err != nil || !isValid) { 23 // Token expired - attempt transparent refresh 24 refreshToken, err := c.Cookie("refreshToken") 25 if err == nil && refreshToken != "" { 26 decryptedRefreshToken := decrypt(refreshToken) 27 authResult, err := scalekitClient.RefreshAccessToken(c.Request.Context(), decryptedRefreshToken) 28 29 if err == nil { 30 // Encrypt and store new tokens 31 c.SetSameSite(http.SameSiteStrictMode) 32 c.SetCookie( 33 "accessToken", 34 encrypt(authResult.AccessToken), 35 authResult.ExpiresIn-60, 36 "/", 37 "", 38 os.Getenv("GIN_MODE") == "release", 39 true, 40 ) 41 c.SetCookie( 42 "refreshToken", 43 encrypt(authResult.RefreshToken), 44 0, 45 "/", 46 "", 47 os.Getenv("GIN_MODE") == "release", 48 true, 49 ) 50 c.Next() 51 return 52 } 53 } 54 55 c.JSON(http.StatusUnauthorized, gin.H{"error": "Session expired. Please sign in again."}) 56 c.Abort() 57 return 58 } 59 60 // Token is valid, proceed to the next handler in the chain 61 c.Next() 62 } 63 } ``` * FastAPI middleware/AuthInterceptor.java ```java 1 import javax.servlet.http.HttpServletRequest; 2 import javax.servlet.http.HttpServletResponse; 3 import javax.servlet.http.Cookie; 4 import org.springframework.web.servlet.HandlerInterceptor; 5 import org.springframework.core.env.Environment; 6 7 /** 8 * Intercepts HTTP requests to verify authentication tokens. 9 * Transparently refreshes expired tokens to maintain user sessions. 10 */ 11 @Component 12 public class AuthInterceptor implements HandlerInterceptor { 13 @Autowired 14 private Environment env; 15 16 @Override 17 public boolean preHandle( 18 HttpServletRequest request, 19 HttpServletResponse response, 20 Object handler 21 ) throws Exception { 22 // Extract encrypted tokens from cookies 23 String accessToken = getCookieValue(request, "accessToken"); 24 String refreshToken = getCookieValue(request, "refreshToken"); 25 26 if (accessToken == null) { 27 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 28 response.getWriter().write("{\"error\": \"Authentication required\"}"); 29 return false; 30 } 31 32 try { 33 // Decrypt the access token before validation 34 String decryptedAccessToken = decrypt(accessToken); 35 36 // Verify token validity using Scalekit's validation method 37 boolean isValid = scalekitClient.validateAccessToken(decryptedAccessToken); 38 39 if (!isValid && refreshToken != null) { 40 // Token expired - refresh it transparently 41 String decryptedRefreshToken = decrypt(refreshToken); 42 AuthResult authResult = scalekitClient.authentication().refreshToken(decryptedRefreshToken); 43 44 // Encrypt and store new tokens 45 Cookie accessTokenCookie = new Cookie("accessToken", encrypt(authResult.getAccessToken())); 46 accessTokenCookie.setMaxAge(authResult.getExpiresIn() - 60); 47 accessTokenCookie.setHttpOnly(true); 48 accessTokenCookie.setSecure("production".equals(env.getActiveProfiles()[0])); 49 accessTokenCookie.setPath("/"); 50 response.addCookie(accessTokenCookie); 51 52 Cookie refreshTokenCookie = new Cookie("refreshToken", encrypt(authResult.getRefreshToken())); 53 refreshTokenCookie.setHttpOnly(true); 54 refreshTokenCookie.setSecure("production".equals(env.getActiveProfiles()[0])); 55 refreshTokenCookie.setPath("/"); 56 response.addCookie(refreshTokenCookie); 57 response.setHeader("Set-Cookie", response.getHeader("Set-Cookie") + "; SameSite=Strict"); 58 59 return true; 60 } 61 62 if (!isValid) { 63 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 64 response.getWriter().write("{\"error\": \"Session expired. Please sign in again.\"}"); 65 return false; 66 } 67 68 // Token is valid, allow request to proceed 69 return true; 70 } catch (Exception e) { 71 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 72 response.getWriter().write("{\"error\": \"Authentication failed\"}"); 73 return false; 74 } 75 } 76 77 private String getCookieValue(HttpServletRequest request, String cookieName) { 78 Cookie[] cookies = request.getCookies(); 79 if (cookies != null) { 80 for (Cookie cookie : cookies) { 81 if (cookieName.equals(cookie.getName())) { 82 return cookie.getValue(); 83 } 84 } 85 } 86 return null; 87 } 88 } ``` 3. ## Configure session security and duration [Section titled “Configure session security and duration”](#configure-session-security-and-duration) Manage user session behavior directly from your Scalekit dashboard without modifying application code. Configure session durations and authentication frequency to balance security and user experience for your application. ![Scalekit Session Policy page with fields for absolute session timeout, idle session timeout, and access token lifetime](/.netlify/images?url=_astro%2Fsession-policies-dashboard.CedTumlx.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) In your Scalekit dashboard, the **Session settings** page lets you set these options: * **Absolute session timeout**: This is the maximum time a user can stay signed in, no matter what. After this time, they must log in again. For example, if you set it to 30 minutes, users will be logged out after 30 minutes, even if they are still using your app. * **Idle session timeout**: This is the time your app waits before logging out a user who is not active. If you turn this on, the session will end if the user does nothing for the set time. For example, if you set it to 10 minutes, and the user does not click or type for 10 minutes, they will be logged out. * **Access token lifetime**: This is how long an access token is valid. When it expires, your app needs to get a new token (using the refresh token) so the user can keep using the app without logging in again. For example, if you set it to 5 minutes, your app will need to refresh the token every 5 minutes. Shorter timeouts provide better security, while longer timeouts reduce authentication interruptions. 4. ## Manage sessions remotely API [Section titled “Manage sessions remotely ”](#manage-sessions-remotely-) Beyond client-side session management, Scalekit provides powerful APIs to manage user sessions remotely from your backend application. This enables you to build features like active session management in user account settings, security incident response, or administrative session control. These APIs are particularly useful for: * Displaying all active sessions in user account settings * Allowing users to revoke specific sessions from unfamiliar devices * Security incident response and suspicious session termination - Node.js Session Management SDK ```javascript 1 // Get details for a specific session 2 const sessionDetails = await scalekit.session.getSession('ses_1234567890123456'); 3 4 // List all sessions for a user with optional filtering 5 const userSessions = await scalekit.session.getUserSessions('usr_1234567890123456', { 6 pageSize: 10, 7 filter: { 8 status: ['ACTIVE'], // Filter for active sessions only 9 startTime: new Date('2025-01-01T00:00:00Z'), 10 endTime: new Date('2025-12-31T23:59:59Z') 11 } 12 }); 13 14 // Revoke a specific session (useful for "Sign out this device" functionality) 15 const revokedSession = await scalekit.session.revokeSession('ses_1234567890123456'); 16 17 // Revoke all sessions for a user (useful for "Sign out all devices" functionality) 18 const revokedSessions = await scalekit.session.revokeAllUserSessions('usr_1234567890123456'); 19 console.log(`Revoked sessions for user`); ``` - Python Session Management SDK ```python 1 # Get details for a specific session 2 session_details = scalekit_client.sessions.get_session(session_id="ses_1234567890123456") 3 4 # List all sessions for a user with optional filtering 5 from google.protobuf.timestamp_pb2 import Timestamp 6 from datetime import datetime 7 8 start_time = Timestamp() 9 start_time.FromDatetime(datetime(2025, 1, 1)) 10 end_time = Timestamp() 11 end_time.FromDatetime(datetime(2025, 12, 31)) 12 13 filter_obj = scalekit_client.sessions.create_session_filter( 14 status=["ACTIVE"], start_time=start_time, end_time=end_time 15 ) 16 user_sessions = scalekit_client.sessions.get_user_sessions( 17 user_id="usr_1234567890123456", page_size=10, filter=filter_obj 18 ) 19 20 # Revoke a specific session (useful for "Sign out this device" functionality) 21 revoked_session = scalekit_client.sessions.revoke_session(session_id="ses_1234567890123456") 22 23 # Revoke all sessions for a user (useful for "Sign out all devices" functionality) 24 revoked_sessions = scalekit_client.sessions.revoke_all_user_sessions(user_id="usr_1234567890123456") 25 print(f"Revoked sessions for user") ``` - Go Session Management SDK ```go 1 // Get details for a specific session 2 sessionDetails, err := scalekitClient.Session().GetSession(ctx, "ses_1234567890123456") 3 if err != nil { 4 log.Fatal(err) 5 } 6 7 // List all sessions for a user with optional filtering 8 // import "time", sessionsv1 "...", "google.golang.org/protobuf/types/known/timestamppb" 9 startTime, _ := time.Parse(time.RFC3339, "2025-01-01T00:00:00Z") 10 endTime, _ := time.Parse(time.RFC3339, "2025-12-31T23:59:59Z") 11 filter := &sessionsv1.UserSessionFilter{ 12 Status: []string{"ACTIVE"}, // Filter for active sessions only 13 StartTime: timestamppb.New(startTime), 14 EndTime: timestamppb.New(endTime), 15 } 16 userSessions, err := scalekitClient.Session().GetUserSessions(ctx, "usr_1234567890123456", 10, "", filter) 17 if err != nil { 18 log.Fatal(err) 19 } 20 21 // Revoke a specific session (useful for "Sign out this device" functionality) 22 revokedSession, err := scalekitClient.Session().RevokeSession(ctx, "ses_1234567890123456") 23 if err != nil { 24 log.Fatal(err) 25 } 26 27 // Revoke all sessions for a user (useful for "Sign out all devices" functionality) 28 revokedSessions, err := scalekitClient.Session().RevokeAllUserSessions(ctx, "usr_1234567890123456") 29 if err != nil { 30 log.Fatal(err) 31 } 32 fmt.Printf("Revoked sessions for user") ``` - Java Session Management SDK ```java 1 // Get details for a specific session 2 SessionDetails sessionDetails = scalekitClient.sessions().getSession("ses_1234567890123456"); 3 4 // List all sessions for a user with optional filtering 5 // import UserSessionFilter, Timestamp, Instant 6 UserSessionFilter filter = UserSessionFilter.newBuilder() 7 .addStatus("ACTIVE") 8 .setStartTime(Timestamp.newBuilder().setSeconds(Instant.parse("2025-01-01T00:00:00Z").getEpochSecond()).build()) 9 .setEndTime(Timestamp.newBuilder().setSeconds(Instant.parse("2025-12-31T23:59:59Z").getEpochSecond()).build()) 10 .build(); 11 UserSessionDetails userSessions = scalekitClient.sessions().getUserSessions("usr_1234567890123456", 10, "", filter); 12 13 // Revoke a specific session (useful for "Sign out this device" functionality) 14 RevokeSessionResponse revokedSession = scalekitClient.sessions().revokeSession("ses_1234567890123456"); 15 16 // Revoke all sessions for a user (useful for "Sign out all devices" functionality) 17 RevokeAllUserSessionsResponse revokedSessions = scalekitClient.sessions().revokeAllUserSessions("usr_1234567890123456"); 18 System.out.println("Revoked sessions for user"); ``` After you add the helper, open `/account` in the browser. A missing session goes to `/login`. After login, the browser returns to `/account`. Session middleware validates `sk_session` on each request and refreshes it before expiry. If the refresh token is invalid, the helper sends the browser to `/login`. --- # DOCUMENT BOUNDARY --- # Manage applications > Register and manage applications in your shared authentication system Register and manage applications in Scalekit. Each application gets its own OAuth client and configuration while sharing the same underlying user session across your web, mobile, and desktop apps. 1. ## Navigate to Applications [Section titled “Navigate to Applications”](#navigate-to-applications) 1. Sign in to **** 2. From the left sidebar, go to **Developers > Applications** You will see a list of applications already created for the selected environment. 2. ## Create a new application [Section titled “Create a new application”](#create-a-new-application) Click **Create Application** to add a new app. You’ll be asked to provide: * **Application name** — A human-readable name for identifying the app * **Application type** — Determines how authentication and credentials work Available application types: * **Web Application** — Server-side applications that can securely store secrets * **Single Page Application (SPA)** — Browser-based applications; public clients with PKCE enforced * **Native Application** — Desktop or mobile apps; public clients with PKCE enforced ![Create application modal showing app name and type selection](/.netlify/images?url=_astro%2Fweb-modal.BXg9RPmN.png\&w=1124\&h=944\&dpl=6aaa70ad2ea7b40008ad2afd) Once created, Scalekit generates a **Client ID**. Only Web Applications can generate **Client Secrets**. 3. ## Application configuration [Section titled “Application configuration”](#application-configuration) ### Application details [Section titled “Application details”](#application-details) Open an application to view and edit its configuration. * **Allow Scalekit Management API access** — Enables this application’s credentials to call Scalekit Management APIs. Applicable only to **Web Applications**. * **Enforce PKCE** — Requires PKCE for authorization requests. Always enabled and not editable for **SPA** and **Native** applications. * **Access token expiry time** — Overrides the environment default access token lifetime for this application. Access token expiry must be shorter than idle session timeout If tokens outlive the session, users may encounter inconsistent logout behavior across apps. When the session expires but the access token is still valid, subsequent token refresh attempts will fail because the underlying session no longer exists. ![Application details page with configuration options](/.netlify/images?url=_astro%2Fweb-app-details.BZtG_A3x.png\&w=1640\&h=1100\&dpl=6aaa70ad2ea7b40008ad2afd) ### Client credentials [Section titled “Client credentials”](#client-credentials) Each application has a unique **Client ID**. When you generate a new client secret, Scalekit shows it **only once**. Copy and store it securely. Treat client secrets like passwords Anyone with access to your client secret can authenticate as your application and obtain tokens for any user. Never commit secrets to version control, expose them in client-side code, or share them in plain text. Use environment variables or a secrets manager. * **Web Applications** * Can generate a **Client Secret** * A maximum of **two active secrets** is allowed at a time * Generating a new secret always creates a **new value**, enabling safe rotation ![Client credentials section showing Client ID and secret management](/.netlify/images?url=_astro%2Fweb-client-creds.aNZmxstS.png\&w=1214\&h=628\&dpl=6aaa70ad2ea7b40008ad2afd) * **SPA and Native Applications** * Do not have client secrets * Authenticate using Authorization Code with PKCE only ![SPA client ID section without client secret option](/.netlify/images?url=_astro%2Fspa-client-id.DFzivdPM.png\&w=1168\&h=412\&dpl=6aaa70ad2ea7b40008ad2afd) 4. ## Configure redirect URLs [Section titled “Configure redirect URLs”](#configure-redirect-urls) Open the **Redirects** tab for an application to manage redirect endpoints. These URLs act as an allowlist and control where Scalekit can redirect users during authentication flows. ### Redirect URL types [Section titled “Redirect URL types”](#redirect-url-types) * **Post login URLs** — Allowed values for `redirect_uri` used with `/oauth/authorize` * **Initiate login URL** — Where Scalekit redirects users when authentication starts outside your app * **Post logout URLs** — Where users are redirected after a successful logout * **Back-channel logout URL** — A secure endpoint that Scalekit calls to notify your application that a user session has been revoked ![Redirect URLs configuration tab with URL types](/.netlify/images?url=_astro%2Fweb-app-redirects.CqgtckPK.png\&w=2604\&h=1396\&dpl=6aaa70ad2ea7b40008ad2afd) For definitions, validation rules, custom URI schemes, and environment-specific behavior, see [Redirect URL configuration](/guides/dashboard/redirects/). 5. ## Delete an application [Section titled “Delete an application”](#delete-an-application) Delete applications from the bottom of the configuration page. ![Delete application button at bottom of configuration page](/.netlify/images?url=_astro%2Fdelete-app.Bz8WrFNb.png\&w=2556\&h=194\&dpl=6aaa70ad2ea7b40008ad2afd) Deleting an application is permanent This action is **permanent and irreversible**. Existing refresh tokens associated with the application will no longer be valid, and users will need to re-authenticate. Ensure you have communicated this change to affected users before deleting. --- # DOCUMENT BOUNDARY --- # Mobile & desktop applications > Implement Multi-App Authentication for mobile and desktop apps using Authorization Code with PKCE Implement login, token management, and logout in your mobile or desktop application using Authorization Code with PKCE. Native apps are public OAuth clients that cannot securely store a `client_secret` in the application binary, so they use PKCE to protect the authorization flow. This guide covers initiating login through the system browser, handling deep link callbacks, managing tokens in secure storage, and implementing logout. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) Before you begin, ensure you have: * A Scalekit account with an environment configured * Your environment URL (`ENV_URL`), e.g., `https://yourenv.scalekit.com` * A native application registered in Scalekit with a `client_id` ([Create one](/authenticate/fsa/multiapp/manage-apps)) * A callback URI configured: * **Mobile**: Custom URI scheme (e.g., `myapp://callback`) or universal/app links * **Desktop**: Custom URI scheme or loopback address (e.g., `http://127.0.0.1:PORT/callback`) ## High-level flow [Section titled “High-level flow”](#high-level-flow) ## Step-by-step implementation [Section titled “Step-by-step implementation”](#step-by-step-implementation) 1. ## Initiate login or signup [Section titled “Initiate login or signup”](#initiate-login-or-signup) Initiate login by opening the system browser with the authorization URL. Always use the system browser rather than an embedded WebView — this lets users leverage existing sessions and provides a familiar, secure authentication experience. ```sh 1 /oauth/authorize? 2 response_type=code& 3 client_id=& 4 redirect_uri=& 5 scope=openid+profile+email+offline_access& 6 state=& 7 code_challenge=& 8 code_challenge_method=S256 ``` Generate and store these values before opening the browser: * `state` — Validate this on callback to prevent CSRF attacks * `code_verifier` — A cryptographically random string you keep in the app * `code_challenge` — Derived from the verifier using S256 hashing; send this in the authorization URL For detailed parameter definitions, see [Initiate signup/login](/authenticate/fsa/implement-login). 2. ## Handle the callback and complete login [Section titled “Handle the callback and complete login”](#handle-the-callback-and-complete-login) After authentication, Scalekit redirects the user back to your application using the registered callback mechanism. Common callback patterns: * **Mobile apps** — Custom URI schemes (e.g., `myapp://callback`) or universal links (iOS) / app links (Android) * **Desktop apps** — Custom URI schemes or a temporary HTTP server on localhost Your callback handler must: * Validate the returned `state` matches what you stored — this confirms the response is for your original request * Handle any error parameters before processing * Exchange the authorization code for tokens by including the `code_verifier` ```sh 1 POST /oauth/token 2 Content-Type: application/x-www-form-urlencoded 3 4 grant_type=authorization_code& 5 client_id=& 6 code=& 7 redirect_uri=& 8 code_verifier= ``` ```json 1 { 2 "access_token": "...", 3 "refresh_token": "...", 4 "id_token": "...", 5 "expires_in": 299 6 } ``` 3. ## Manage sessions and token refresh [Section titled “Manage sessions and token refresh”](#manage-sessions-and-token-refresh) Store tokens in platform-specific secure storage and validate them on each request. When access tokens expire, use the refresh token to obtain new ones without requiring the user to re-authenticate. **Token roles** * **Access token** — Short-lived token (default 5 minutes) for authenticated API requests * **Refresh token** — Long-lived token to obtain new access tokens * **ID token** — JWT containing user identity claims; required for logout Store tokens using secure, OS-backed storage appropriate for each platform. See [Token storage security](#token-storage-security) for platform-specific recommendations. When an access token expires, request new tokens: ```sh 1 POST /oauth/token 2 Content-Type: application/x-www-form-urlencoded 3 4 grant_type=refresh_token& 5 client_id=& 6 refresh_token= ``` Validate access tokens by verifying: * Token signature using Scalekit’s public keys (JWKS endpoint) * `iss` matches your Scalekit environment URL * `aud` includes your `client_id` * `exp` and `iat` are valid timestamps Public keys for signature verification: ```sh 1 /keys ``` 4. ## Implement logout [Section titled “Implement logout”](#implement-logout) Clear your local session and redirect the system browser to Scalekit’s logout endpoint to invalidate the shared session. Your logout action must: * Extract the ID token before clearing local storage * Clear tokens from secure storage * Open the system browser to Scalekit’s logout endpoint ```sh 1 /oidc/logout? 2 id_token_hint=& 3 post_logout_redirect_uri= ``` ## Handle errors [Section titled “Handle errors”](#handle-errors) When authentication fails, Scalekit redirects to your callback URI with error parameters instead of an authorization code: ```plaintext 1 myapp://callback?error=access_denied&error_description=User+denied+access&state= ``` Check for errors before processing the authorization code: * Check if the `error` parameter exists in the callback URI * Log the `error` and `error_description` for debugging * Display a user-friendly message in your app * Provide an option to retry login Common error codes: | Error | Description | | ----------------- | ------------------------------------------------------------ | | `access_denied` | User denied the authorization request | | `invalid_request` | Missing or invalid parameters (e.g., invalid PKCE challenge) | | `server_error` | Scalekit encountered an unexpected error | ## Token storage security [Section titled “Token storage security”](#token-storage-security) Native apps have access to platform-specific secure storage mechanisms that encrypt tokens at rest and protect them from other applications. Unlike browser storage, these mechanisms provide strong protection against token theft from device compromise or malware. Use platform-specific secure storage for each platform: | Platform | Recommended Storage | | -------- | -------------------------------------- | | iOS | Keychain Services | | Android | EncryptedSharedPreferences or Keystore | | macOS | Keychain | | Windows | Windows Credential Manager or DPAPI | | Linux | Secret Service API (libsecret) | **Recommendations:** * Never store tokens in plain text files, shared preferences, or unencrypted databases — these can be read by any application with storage access * Use biometric or device PIN protection for sensitive token access when available — this adds a second factor for token access * Clear tokens from secure storage on logout — this ensures a clean state for the next authentication Never embed secrets in your application binary Credentials embedded in application code or configuration files can be extracted through reverse engineering. Always use PKCE for native apps instead of relying on a `client_secret`. If you need to make authenticated API calls from your backend, use a separate web application with proper secret management. ## What’s next [Section titled “What’s next”](#whats-next) * [Set up a custom domain](/guides/custom-domain) for your authentication pages * [Add enterprise SSO](/authenticate/auth-methods/enterprise-sso/) to support SAML and OIDC with your customers’ identity providers --- # DOCUMENT BOUNDARY --- # Single page application > Implement Multi-App Authentication for single page apps using Authorization Code with PKCE Implement login, token management, and logout in your single page application (SPA) using Authorization Code with PKCE. SPAs run entirely in the browser and cannot securely store a `client_secret`, so they use PKCE (Proof Key for Code Exchange) to protect the authorization flow. This guide covers initiating login from your SPA, exchanging authorization codes for tokens, managing sessions, and implementing logout. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) Before you begin, ensure you have: * A Scalekit account with an environment configured * Your environment URL (`ENV_URL`), e.g., `https://yourenv.scalekit.com` * A SPA registered in Scalekit with a `client_id` ([Create one](/authenticate/fsa/multiapp/manage-apps)) * At least one redirect URL configured in **Dashboard > Developers > Applications > \[Your App] > Redirects** ## High-level flow [Section titled “High-level flow”](#high-level-flow) ## Step-by-step implementation [Section titled “Step-by-step implementation”](#step-by-step-implementation) 1. ## Initiate login or signup [Section titled “Initiate login or signup”](#initiate-login-or-signup) Initiate login by redirecting the user to Scalekit’s hosted login page. Include the PKCE code challenge in the authorization request to protect against authorization code interception attacks. ```sh 1 /oauth/authorize? 2 response_type=code& 3 client_id=& 4 redirect_uri=& 5 scope=openid+profile+email+offline_access& 6 state=& 7 code_challenge=& 8 code_challenge_method=S256 ``` Generate and store these values before redirecting: * `state` — Validate this on callback to prevent CSRF attacks * `code_verifier` — A cryptographically random string you keep locally * `code_challenge` — Derived from the verifier using S256 hashing; send this in the authorization URL For detailed parameter definitions, see [Initiate signup/login](/authenticate/fsa/implement-login). 2. ## Handle the callback and complete login [Section titled “Handle the callback and complete login”](#handle-the-callback-and-complete-login) After authentication, Scalekit redirects the user back to your callback URL with an authorization `code` and the `state` you sent. Your callback handler must: * Validate the returned `state` matches what you stored — this confirms the response is for your original request * Handle any error parameters before processing * Exchange the authorization code for tokens by including the `code_verifier` ```sh 1 POST /oauth/token 2 Content-Type: application/x-www-form-urlencoded 3 4 grant_type=authorization_code& 5 client_id=& 6 code=& 7 redirect_uri=& 8 code_verifier= ``` ```json 1 { 2 "access_token": "...", 3 "refresh_token": "...", 4 "id_token": "...", 5 "expires_in": 299 6 } ``` 3. ## Manage sessions and token refresh [Section titled “Manage sessions and token refresh”](#manage-sessions-and-token-refresh) Store tokens and validate them on each request. When access tokens expire, use the refresh token to obtain new ones without requiring the user to authenticate again. **Token roles** * **Access token** — Short-lived token (default 5 minutes) for authenticated API requests * **Refresh token** — Long-lived token to obtain new access tokens * **ID token** — JWT containing user identity claims; required for logout Store tokens client-side based on your security requirements. See [Token storage security](#token-storage-security) for guidance on choosing the right storage mechanism. When an access token expires, request new tokens: ```sh 1 POST /oauth/token 2 Content-Type: application/x-www-form-urlencoded 3 4 grant_type=refresh_token& 5 client_id=& 6 refresh_token= ``` Validate access tokens by verifying: * Token signature using Scalekit’s public keys (JWKS endpoint) * `iss` matches your Scalekit environment URL * `aud` includes your `client_id` * `exp` and `iat` are valid timestamps Public keys for signature verification: ```sh 1 /keys ``` 4. ## Implement logout [Section titled “Implement logout”](#implement-logout) Clear your local session and redirect to Scalekit’s logout endpoint to invalidate the shared session. Your logout action must: * Extract the ID token before clearing local storage * Clear locally stored tokens from memory or storage * Redirect the browser to Scalekit’s logout endpoint ```sh 1 /oidc/logout? 2 id_token_hint=& 3 post_logout_redirect_uri= ``` ## Handle errors [Section titled “Handle errors”](#handle-errors) When authentication fails, Scalekit redirects to your callback URL with error parameters instead of an authorization code: ```sh /callback?error=access_denied&error_description=User+denied+access&state= ``` Check for errors before processing the authorization code: * Check if the `error` parameter exists in the URL * Log the `error` and `error_description` for debugging * Display a user-friendly message * Provide an option to retry login Common error codes: | Error | Description | | ----------------- | ------------------------------------------------------------ | | `access_denied` | User denied the authorization request | | `invalid_request` | Missing or invalid parameters (e.g., invalid PKCE challenge) | | `server_error` | Scalekit encountered an unexpected error | ## Token storage security [Section titled “Token storage security”](#token-storage-security) SPAs run entirely in the browser where tokens are vulnerable to cross-site scripting (XSS) attacks. An attacker who successfully injects malicious JavaScript can read tokens from any accessible storage and use them to impersonate the user. Choose a storage strategy based on your security requirements: | Storage | Security | Trade-off | | ---------------------------- | --------------------------------------- | ---------------------------------------------------- | | Memory (JavaScript variable) | Most secure — not accessible to XSS | Tokens lost on page refresh; requires silent refresh | | Session storage | Moderate — cleared when tab closes | Accessible to XSS; persists during session | | Local storage | Least secure — persists across sessions | Accessible to XSS; long exposure window | **Recommendations:** * For high-security applications, store tokens in memory and use silent refresh (iframe-based token renewal) to maintain sessions across page loads * Always sanitize user inputs and use Content Security Policy (CSP) headers to mitigate XSS attacks * Never log tokens or include them in error messages Never store tokens in local storage for sensitive applications Local storage is accessible to any JavaScript running on your page. If an attacker exploits an XSS vulnerability, they can read all tokens from local storage and fully compromise user accounts. For applications handling sensitive data, prefer memory storage with silent refresh. ## What’s next [Section titled “What’s next”](#whats-next) * [Set up a custom domain](/guides/custom-domain) for your authentication pages * [Add enterprise SSO](/authenticate/auth-methods/enterprise-sso/) to support SAML and OIDC with your customers’ identity providers --- # DOCUMENT BOUNDARY --- # Web application > Implement Multi-App Authentication for web apps using Authorization Code flow with client_id and client_secret Implement login, token management, and logout in your web application using the Authorization Code flow. Web applications have a backend server that can securely store a `client_secret`, allowing them to authenticate directly with Scalekit’s token endpoint. This guide covers initiating login from your backend, exchanging authorization codes for tokens, managing sessions with secure cookies, and implementing logout. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) Before you begin, ensure you have: * A Scalekit account with an environment configured * Your environment URL (`ENV_URL`), e.g., `https://yourenv.scalekit.com` * A web application registered in Scalekit with `client_id` and `client_secret` ([Create one](/authenticate/fsa/multiapp/manage-apps)) * At least one redirect URL configured in **Dashboard > Developers > Applications > \[Your App] > Redirects** ## High-level flow [Section titled “High-level flow”](#high-level-flow) ## Step-by-step implementation [Section titled “Step-by-step implementation”](#step-by-step-implementation) 1. ## Initiate login or signup [Section titled “Initiate login or signup”](#initiate-login-or-signup) Initiate login by redirecting the user to Scalekit’s hosted login page from your backend. Generate and store a `state` parameter before redirecting to validate the callback. ```sh 1 /oauth/authorize? 2 response_type=code& 3 client_id=& 4 redirect_uri=& 5 scope=openid+profile+email+offline_access& 6 state= ``` For detailed parameter definitions, see [Initiate signup/login](/authenticate/fsa/implement-login). 2. ## Handle the callback and complete login [Section titled “Handle the callback and complete login”](#handle-the-callback-and-complete-login) After authentication, Scalekit redirects the user back to your callback endpoint with an authorization `code` and the `state` you sent. Your backend must: * Validate the returned `state` matches what you stored — this confirms the response is for your original request and prevents CSRF attacks * Handle any error parameters before processing * Exchange the authorization code for tokens using your `client_secret` ```sh 1 POST /oauth/token 2 Content-Type: application/x-www-form-urlencoded 3 4 grant_type=authorization_code& 5 client_id=& 6 client_secret=& 7 code=& 8 redirect_uri= ``` ```json 1 { 2 "access_token": "...", 3 "refresh_token": "...", 4 "id_token": "...", 5 "expires_in": 299 6 } ``` 3. ## Manage sessions and token refresh [Section titled “Manage sessions and token refresh”](#manage-sessions-and-token-refresh) Store tokens in secure cookies and validate the access token on each request. When access tokens expire, use the refresh token to obtain new ones without requiring the user to re-authenticate. **Token roles** * **Access token** — Short-lived token (default 5 minutes) for authenticated API requests * **Refresh token** — Long-lived token to obtain new access tokens * **ID token** — JWT containing user identity claims; required for logout Store tokens in secure, HttpOnly cookies with appropriate path scoping to limit exposure. When an access token expires, request new tokens: ```sh 1 POST /oauth/token 2 Content-Type: application/x-www-form-urlencoded 3 4 grant_type=refresh_token& 5 client_id=& 6 client_secret=& 7 refresh_token= ``` Validate access tokens by verifying: * Token signature using Scalekit’s public keys (JWKS endpoint) * `iss` matches your Scalekit environment URL * `aud` includes your `client_id` * `exp` and `iat` are valid timestamps Public keys for signature verification: ```sh 1 /keys ``` 4. ## Implement logout [Section titled “Implement logout”](#implement-logout) Clear your application session and redirect to Scalekit’s logout endpoint to invalidate the shared session. Your logout endpoint must: * Extract the ID token before clearing cookies * Clear application session cookies * Redirect the browser to Scalekit’s logout endpoint ```sh 1 /oidc/logout? 2 id_token_hint=& 3 post_logout_redirect_uri= ``` Configure [backchannel logout](/guides/dashboard/redirects/#back-channel-logout-url) URLs to receive notifications when a logout is performed from another application sharing the same user session. ## Handle errors [Section titled “Handle errors”](#handle-errors) When authentication fails, Scalekit redirects to your callback URL with error parameters instead of an authorization code: ```sh /callback?error=access_denied&error_description=User+denied+access&state= ``` Check for errors before processing the authorization code: * Check if the `error` parameter exists in the URL * Log the `error` and `error_description` for debugging * Display a user-friendly message * Provide an option to retry login Common error codes: | Error | Description | | ----------------- | ---------------------------------------- | | `access_denied` | User denied the authorization request | | `invalid_request` | Missing or invalid parameters | | `server_error` | Scalekit encountered an unexpected error | ## (Optional) Use Scalekit Management APIs [Section titled “(Optional) Use Scalekit Management APIs”](#optional-use-scalekit-management-apis) In addition to handling user authentication, web applications can call Scalekit’s Management APIs from the backend. These APIs allow your application to interact with Scalekit-managed resources such as users, organizations, memberships, and roles. Typical use cases include: * Fetching the currently authenticated user * Listing organizations the user belongs to * Managing organization membership or roles Management APIs are Scalekit-owned APIs intended for server-side use only. Enable Management API access in your application: 1. Go to **app.scalekit.com** 2. Navigate to **Developers > Applications** 3. Select your **Web Application** 4. Enable **Allow Scalekit Management API Access** ## What’s next [Section titled “What’s next”](#whats-next) * [Configure backchannel logout](/guides/dashboard/redirects/#back-channel-logout-url) to receive notifications when a user logs out from another app * [Set up a custom domain](/guides/custom-domain) for your authentication pages * [Add enterprise SSO](/authenticate/auth-methods/enterprise-sso/) to support SAML and OIDC with your customers’ identity providers --- # DOCUMENT BOUNDARY --- # Customize session token claims > Add custom claims from a user profile and organization to the JWT access token Scalekit issues at login and session refresh A session token claim adds a field from a user’s profile or their organization directly onto the JWT access token Scalekit issues at login and session refresh. Your API reads it straight off the token, instead of looking it up from your own database on every request. ## How it works [Section titled “How it works”](#how-it-works) Every access token Scalekit issues carries a working set of default claims, resolved fresh each time a session starts or refreshes: Default access token claims ```jsonc { "sub": "usr_96194455173923084", // Scalekit user ID "iss": "https://your-app.scalekit.com", // Token issuer "aud": ["https://api.your-app.com"], // Intended audience "exp": 1730000600, // Expiration time "iat": 1730000000, // Issued-at time "nbf": 1730000000, // Not valid before "jti": "tkn_2b91b6b8f1e94b2c", // Unique token ID "sid": "ses_5f3a9c1d7e2b4a68", // Session ID "oid": "org_84213988219092123", // Organization ID "roles": ["admin"], // Roles in the organization "permissions": ["users:read", "users:write"] // Permissions granted } ``` A custom claim works the same way. You define an expression once, against `user` or `organization`, and Scalekit resolves it for every session from then on, adding the result alongside the default claims above. These claims are also listed in your Scalekit dashboard, under **Dashboard > Authentication > Token Claims**. ## Add a custom claim [Section titled “Add a custom claim”](#add-a-custom-claim) To add a custom claim: 1. Navigate to **Dashboard > Authentication > Token Claims** and click **Add custom claim**. 2. Configure the new claim: * **Claim key** - the name it appears under in the token, for example `plan`. * **Expression** - the dot-path to the value, evaluated against `user` or `organization`, for example `organization.metadata.plan`. 3. Click **Add**. Scalekit applies the claim immediately, there’s no separate publish step. Reserved claim keys `sub`, `iss`, `aud`, `exp`, `iat`, `nbf`, `jti`, `oid`, `sid`, `xoid`, `xuid`, `roles`, and `permissions` are already set by Scalekit. Pick a claim key that doesn’t collide with these, like `plan` or `a_user_email`. ![Add custom claim panel with a claim key field and an expression field.](/.netlify/images?url=_astro%2Fadd-custom-claim.CvEzhmu5.png\&w=3432\&h=1922\&dpl=6aaa70ad2ea7b40008ad2afd) Scalekit adds the resolved value to every token going forward: Access token with a custom claim ```diff { "sub": "usr_96194455173923084", // Scalekit user ID "iss": "https://your-app.scalekit.com", // Token issuer "aud": ["https://api.your-app.com"], // Intended audience "exp": 1730000600, // Expiration time "iat": 1730000000, // Issued-at time "nbf": 1730000000, // Not valid before "jti": "tkn_2b91b6b8f1e94b2c", // Unique token ID "sid": "ses_5f3a9c1d7e2b4a68", // Session ID "oid": "org_84213988219092123", // Organization ID "roles": ["admin"], // Roles in the organization "permissions": ["users:read", "users:write"], // Permissions granted "plan": "enterprise" // Custom claim from organization.metadata.plan } ``` Custom claims are access token extensions you can precisely configure for your application’s authorization needs. For example, as a multi-tenant SaaS platform, you might add a claim that exposes the organization’s plan, so your API can gate a premium feature without a database lookup on every request. Use the pencil icon next to a claim to edit its expression, or the trash icon to remove it. Keep claims non-sensitive Anyone holding the access token can decode and read its claims, and tokens are often logged or forwarded to other services. Include only the minimal context your API needs to authorize a request, such as a plan tier or a role, and never a secret, password, or unnecessary personal detail. ## Preview before you rely on it [Section titled “Preview before you rely on it”](#preview-before-you-rely-on-it) The **Token preview** panel on the Token Claims page resolves every claim, default and custom, against a real session. Select a user and their organization, and the JSON view updates with the exact payload that session’s token would carry. ![Token Claims page with a user and an organization selected, showing the resolved JWT payload in the preview panel.](/.netlify/images?url=_astro%2Ftoken-claims-page.BQw4NTat.png\&w=3200\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) For a true end-to-end check, sign in through your OIDC flow and decode the access token you receive. A custom claim only reflects the data at the time the token was issued, so an existing token keeps its old value until the user logs in again or the token refreshes. ## User and organization fields [Section titled “User and organization fields”](#user-and-organization-fields) Every expression reads from one of two objects: `user` or `organization`. **User fields:** | Field | Holds | | -------------------------------------------------------------------------------------- | -------------------------------------------------------- | | `user.id` | Scalekit user ID | | `user.email`, `user.email_verified` | Primary email and its verification state | | `user.name`, `user.given_name`, `user.family_name` | Display, first, and last name | | `user.preferred_username` | Preferred username | | `user.phone_number`, `user.phone_number_verified` | Phone number and its verification state | | `user.picture` | URL of the profile picture | | `user.gender` | Gender | | `user.locale` | Language and region preference | | `user.groups` | Groups the user belongs to | | `user.external_id` | Your system’s identifier for this user | | `user.metadata` | Key-value data you’ve attached to the user | | `user.custom_attributes` | Custom profile attributes | | `user.created_at`, `user.updated_at` | When the user account was created and last updated | | `user.last_login_time` | When the user last logged in | | `user.current_membership.organization_id`, `user.current_membership.organization_name` | ID and name of the organization the user is signing into | | `user.current_membership.roles` | Roles the user holds in that organization | | `user.current_membership.status` | Membership status, for example `active` | | `user.current_membership.metadata` | Key-value data on the membership itself | **Organization fields:** | Field | Holds | | -------------------------- | -------------------------------------------------- | | `organization.id` | Scalekit organization ID | | `organization.name` | Organization display name | | `organization.external_id` | Your system’s identifier for this organization | | `organization.metadata` | Key-value data you’ve attached to the organization | ## Write the expression [Section titled “Write the expression”](#write-the-expression) The simplest expression is a field path, like `user.email`. Scalekit evaluates it against the signed-in user and their organization, and the result becomes the claim’s value. Chain a fallback with `??` for when the first field might be missing, for example `user.email ?? user.preferred_username`. It only falls back on a missing or `nil` value, not an empty string. Once a chain goes more than one level below a field that might not exist, add `?.` at that hop instead of a plain `.`. `?.` short-circuits to a missing value the moment the left side is missing, so `??` can still catch it; a plain `.` on a missing value causes a runtime error instead, which `??` can’t resolve. You only need `?.` below the uncertain field, not before it: `organization.metadata` is always present, so `organization.metadata.billing` is safe as-is, but `billing` itself might be missing, so reaching into it needs `organization.metadata.billing?.tier`. A few more patterns: | What you want | Expression | | -------------------------------------------------------- | ----------------------------------------------- | | A profile field | `user.email` | | Something from your own metadata | `organization.metadata.plan` | | A default when a field might be unset | `organization.metadata.plan ?? "free"` | | A default two levels below a field that might be missing | `organization.metadata.billing?.tier ?? "free"` | A few string and array helpers are also available (`split`, `trim`, `len`, `filter`, and more) for anything more involved than a plain lookup. Once your claims are in place, see [Manage user sessions](/authenticate/fsa/manage-session/) for how your application stores, validates, and refreshes the token they’re attached to. --- # DOCUMENT BOUNDARY --- # User management settings > Configure user management settings, including user attributes and configuration options from to Scalekit dashboard. User management settings allow you to configure how user data is handled in the environment and what attributes are available for users in your application. These settings are accessible from the **User Management** section in the Scalekit dashboard. The Configuration tab provides several important settings that control user registration, organization limits, and branding. ![Scalekit dashboard User Management settings tab with toggles for sign-up, user limit per organization, invitation expiry, and organization meta name](/.netlify/images?url=_astro%2F2-configuration.BBcHzaot.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) ### Sign-up for your application [Section titled “Sign-up for your application”](#sign-up-for-your-application) Control whether users can sign up and create new organizations. When enabled, users can register for your application and automatically create a new organization. ### Organization creation limit per user [Section titled “Organization creation limit per user”](#organization-creation-limit-per-user) Define the maximum number of organizations a single user can create. This helps prevent abuse and manage resource usage across your application. ### Limit user sign-ups in an organization [Section titled “Limit user sign-ups in an organization”](#limit-user-sign-ups-in-an-organization) Use this when you need seat caps per organization. For example, when organizations map to departments or when plans include per-org seat limits. To set a limit from the dashboard: ![Organization User limit setting enabled with a maximum of 25 users, including active users and pending invitations](/.netlify/images?url=_astro%2Flimit-org-users.F8VX5klf.png\&w=2454\&h=618\&dpl=6aaa70ad2ea7b40008ad2afd) 1. Go to Organizations → Select an Organization → User management 2. Find Organization limits and set max users per organization. Save changes. New users provisioning to this organizations are blocked until limits are increased. Configure them by updating the organization settings. ### Invitation expiry [Section titled “Invitation expiry”](#invitation-expiry) Configure how long user invitation links remain valid. The default setting of **15 days** ensures that invitations don’t remain active indefinitely, improving security while giving invitees reasonable time to accept. ### Organization meta name [Section titled “Organization meta name”](#organization-meta-name) Customize what you call an “Organization” in your application. This meta name appears throughout all Scalekit-hosted pages. For example, you might call it: * “Company” for B2B applications * “Team” for collaboration tools * “Workspace” for productivity apps * “Account” for multi-tenant systems ## User attributes [Section titled “User attributes”](#user-attributes) The User Attributes tab allows you to define custom fields that will be available for user profiles. These attributes help you collect and store additional information about your users beyond the standard profile fields. ![Scalekit dashboard Users page listing application users with their email and active or inactive status](/.netlify/images?url=_astro%2F1-user-profile.CQCsGgPh.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) When you define custom user attributes, they become part of the user’s profile data that your application can access. This allows you to: * Collect additional information during user registration * Store application-specific user data * Personalize user experiences based on these attributes * Use the data for application logic and user management --- # DOCUMENT BOUNDARY --- # Handle webhook events in your application > Receive real-time notifications about authentication events in your application using Scalekit webhooks Webhooks provide real-time notifications about authentication and user management events in your Scalekit environment. Instead of polling for changes, your application receives instant notifications when users sign up, log in, join organizations, or when other important events occur. Webhooks enable your app to react immediately to changes in your auth stack through: * **Real-time updates**: Get notified immediately when events occur * **Reduced API calls**: No need to poll for changes * **Event-driven architecture**: Build responsive workflows that react to user actions * **Reliable delivery**: Scalekit ensures webhook delivery with automatic retries ## Webhook event object [Section titled “Webhook event object”](#webhook-event-object) All webhook payloads follow a standardized structure with metadata and event-specific data in the `data` field. User created event payload ```json { "spec_version": "1", // The version of the event specification format. Currently "1". "id": "evt_123456789", // A unique identifier for the event (e.g., evt_123456789). "object": "DirectoryUser", // The type of object that triggered the event (e.g., "DirectoryUser", "Directory", "Connection"). "environment_id": "env_123456789", // The ID of the environment where the event occurred. "occurred_at": "2024-08-21T10:20:17.072Z", // ISO 8601 timestamp indicating when the event occurred. "organization_id": "org_123456789", // The ID of the organization associated with the event. "type": "organization.directory.user_created", // The specific event type (e.g., "organization.directory.user_created"). "data": { // Event-specific payload containing details relevant to the event type. "user_id": "usr_123456789", "email": "user@example.com", "name": "John Doe" } } ``` ## Configure webhooks in the dashboard [Section titled “Configure webhooks in the dashboard”](#configure-webhooks-in-the-dashboard) Set up webhook endpoints and select which events you want to receive through the Scalekit dashboard. 1. In your Scalekit dashboard, navigate to **Settings** > **Webhooks** 2. Click **Add Endpoint** and provide: * **Endpoint URL** - Your application’s webhook handler URL (e.g., `https://yourapp.com/webhooks/scalekit`) * **Description** - Optional description for this endpoint 3. Choose which events you want to receive from the dropdown: * **User events** - `user.created`, `user.updated`, `user.deleted` * **Organization events** - `organization.created`, `organization.updated` * **Authentication events** - `session.created`, `session.expired` * **Membership events** - `membership.created`, `membership.updated`, `membership.deleted` 4. Copy the **Signing Secret** - you’ll use this to verify webhook authenticity in your application 5. Use the **Send Test Event** button to verify your endpoint is working correctly ## Implement webhook handlers [Section titled “Implement webhook handlers”](#implement-webhook-handlers) Create secure webhook handlers in your application to process incoming events from Scalekit. 1. ### Set up webhook endpoint [Section titled “Set up webhook endpoint”](#set-up-webhook-endpoint) Create an HTTP POST endpoint in your application to receive webhook payloads from Scalekit. * Node.js Express.js webhook handler ```javascript 1 import express from 'express' 2 import { Scalekit } from '@scalekit-sdk/node' 3 4 const app = express() 5 const scalekit = new Scalekit( 6 process.env.SCALEKIT_ENVIRONMENT_URL, 7 process.env.SCALEKIT_CLIENT_ID, 8 process.env.SCALEKIT_CLIENT_SECRET 9 ) 10 11 // HMAC is over the raw bytes. Parsing JSON first changes whitespace and fails verify. 12 app.use('/webhooks/scalekit', express.raw({ type: 'application/json' })) 13 14 app.post('/webhooks/scalekit', async (req, res) => { 15 const secret = process.env.SCALEKIT_WEBHOOK_SECRET 16 const payload = req.body.toString() 17 const headers = { 18 'webhook-id': req.headers['webhook-id'], 19 'webhook-timestamp': req.headers['webhook-timestamp'], 20 'webhook-signature': req.headers['webhook-signature'], 21 } 22 23 try { 24 scalekit.verifyWebhookPayload(secret, headers, payload) 25 } catch (error) { 26 console.error('Invalid webhook signature') 27 return res.status(401).json({ error: 'Invalid signature' }) 28 } 29 30 const event = JSON.parse(payload) 31 await processWebhookEvent(event) 32 res.status(201).json({ received: true }) 33 }) ``` * Python Flask webhook handler ```python 1 import json 2 import os 3 4 from flask import Flask, jsonify, request 5 from scalekit import ScalekitClient 6 7 app = Flask(__name__) 8 scalekit_client = ScalekitClient( 9 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 10 client_id=os.environ["SCALEKIT_CLIENT_ID"], 11 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 12 ) 13 14 @app.route("/webhooks/scalekit", methods=["POST"]) 15 def handle_webhook(): 16 secret = os.environ.get("SCALEKIT_WEBHOOK_SECRET") 17 raw_body = request.get_data() 18 headers = { 19 "webhook-id": request.headers.get("webhook-id"), 20 "webhook-timestamp": request.headers.get("webhook-timestamp"), 21 "webhook-signature": request.headers.get("webhook-signature"), 22 } 23 24 try: 25 scalekit_client.verify_webhook_payload(secret, headers, raw_body) 26 except Exception: 27 print("Invalid webhook signature") 28 return jsonify({"error": "Invalid signature"}), 401 29 30 event = json.loads(raw_body.decode("utf-8")) 31 process_webhook_event(event) 32 return jsonify({"received": True}), 201 ``` * Go Gin webhook handler ```go 1 package main 2 3 import ( 4 "encoding/json" 5 "io" 6 "net/http" 7 "os" 8 9 "github.com/gin-gonic/gin" 10 scalekit "github.com/scalekit-inc/scalekit-sdk-go" 11 ) 12 13 var scalekitClient = scalekit.NewScalekitClient( 14 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 15 os.Getenv("SCALEKIT_CLIENT_ID"), 16 os.Getenv("SCALEKIT_CLIENT_SECRET"), 17 ) 18 19 func handleWebhook(c *gin.Context) { 20 rawBody, err := io.ReadAll(c.Request.Body) 21 if err != nil { 22 c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to read body"}) 23 return 24 } 25 26 headers := map[string]string{ 27 "webhook-id": c.GetHeader("webhook-id"), 28 "webhook-timestamp": c.GetHeader("webhook-timestamp"), 29 "webhook-signature": c.GetHeader("webhook-signature"), 30 } 31 32 valid, err := scalekitClient.VerifyWebhookPayload( 33 os.Getenv("SCALEKIT_WEBHOOK_SECRET"), 34 headers, 35 rawBody, 36 ) 37 if err != nil || !valid { 38 c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid signature"}) 39 return 40 } 41 42 var event map[string]interface{} 43 if err := json.Unmarshal(rawBody, &event); err != nil { 44 c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON"}) 45 return 46 } 47 48 processWebhookEvent(event) 49 c.JSON(http.StatusCreated, gin.H{"received": true}) 50 } ``` * Java Spring webhook handler ```java 1 import com.fasterxml.jackson.databind.ObjectMapper; 2 import com.scalekit.ScalekitClient; 3 import java.nio.charset.StandardCharsets; 4 import java.util.HashMap; 5 import java.util.Map; 6 import org.springframework.http.HttpStatus; 7 import org.springframework.http.ResponseEntity; 8 import org.springframework.web.bind.annotation.PostMapping; 9 import org.springframework.web.bind.annotation.RequestBody; 10 import org.springframework.web.bind.annotation.RequestHeader; 11 import org.springframework.web.bind.annotation.RestController; 12 13 @RestController 14 public class WebhookController { 15 16 private final ScalekitClient scalekitClient; 17 private final ObjectMapper objectMapper = new ObjectMapper(); 18 19 @PostMapping("/webhooks/scalekit") 20 public ResponseEntity> handleWebhook( 21 @RequestBody String rawBody, 22 @RequestHeader Map requestHeaders 23 ) { 24 Map headers = new HashMap<>(); 25 headers.put("webhook-id", requestHeaders.get("webhook-id")); 26 headers.put("webhook-timestamp", requestHeaders.get("webhook-timestamp")); 27 headers.put("webhook-signature", requestHeaders.get("webhook-signature")); 28 29 try { 30 scalekitClient 31 .webhook() 32 .verifyWebhookPayload( 33 System.getenv("SCALEKIT_WEBHOOK_SECRET"), 34 headers, 35 rawBody.getBytes(StandardCharsets.UTF_8) 36 ); 37 } catch (Exception error) { 38 return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body( 39 Map.of("error", "Invalid signature") 40 ); 41 } 42 43 try { 44 Map event = objectMapper.readValue(rawBody, Map.class); 45 processWebhookEvent(event); 46 return ResponseEntity.status(HttpStatus.CREATED).body(Map.of("received", true)); 47 } catch (Exception error) { 48 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( 49 Map.of("error", "Webhook processing failed") 50 ); 51 } 52 } 53 } ``` 2. ### Process webhook events [Section titled “Process webhook events”](#process-webhook-events) Handle different event types based on your application’s needs. * Node.js Process webhook events ```javascript 1 async function processWebhookEvent(event) { 2 console.log(`Processing event: ${event.type}`); 3 4 switch (event.type) { 5 case 'user.created': 6 // Handle new user registration 7 await handleUserCreated(event.data.user, event.data.organization); 8 break; 9 10 case 'user.updated': 11 // Handle user profile updates 12 await handleUserUpdated(event.data.user); 13 break; 14 15 case 'organization.created': 16 // Handle new organization creation 17 await handleOrganizationCreated(event.data.organization); 18 break; 19 20 case 'membership.created': 21 // Handle user joining organization 22 await handleMembershipCreated(event.data.membership); 23 break; 24 25 default: 26 console.log(`Unhandled event type: ${event.type}`); 27 } 28 } 29 30 async function handleUserCreated(user, organization) { 31 // Use case: Sync new user to your database, send welcome email, set up user workspace 32 console.log(`New user created: ${user.email} in org: ${organization.display_name}`); 33 34 // Sync to your database 35 await syncUserToDatabase(user, organization); 36 37 // Send welcome email 38 await sendWelcomeEmail(user.email, user.first_name); 39 40 // Set up user workspace or default settings 41 await setupUserDefaults(user.id, organization.id); 42 } ``` * Python Process webhook events ```python 1 def process_webhook_event(event): 2 print(f'Processing event: {event["type"]}') 3 4 event_type = event['type'] 5 event_data = event['data'] 6 7 if event_type == 'user.created': 8 # Handle new user registration 9 handle_user_created(event_data['user'], event_data['organization']) 10 elif event_type == 'user.updated': 11 # Handle user profile updates 12 handle_user_updated(event_data['user']) 13 elif event_type == 'organization.created': 14 # Handle new organization creation 15 handle_organization_created(event_data['organization']) 16 elif event_type == 'membership.created': 17 # Handle user joining organization 18 handle_membership_created(event_data['membership']) 19 else: 20 print(f'Unhandled event type: {event_type}') 21 22 def handle_user_created(user, organization): 23 # Use case: Sync new user to your database, send welcome email, set up user workspace 24 print(f'New user created: {user["email"]} in org: {organization["display_name"]}') 25 26 # Sync to your database 27 sync_user_to_database(user, organization) 28 29 # Send welcome email 30 send_welcome_email(user['email'], user['first_name']) 31 32 # Set up user workspace or default settings 33 setup_user_defaults(user['id'], organization['id']) ``` * Go Process webhook events ```go 1 func processWebhookEvent(event map[string]interface{}) { 2 eventType := event["type"].(string) 3 eventData := event["data"].(map[string]interface{}) 4 5 fmt.Printf("Processing event: %s\n", eventType) 6 7 switch eventType { 8 case "user.created": 9 // Handle new user registration 10 user := eventData["user"].(map[string]interface{}) 11 organization := eventData["organization"].(map[string]interface{}) 12 handleUserCreated(user, organization) 13 14 case "user.updated": 15 // Handle user profile updates 16 user := eventData["user"].(map[string]interface{}) 17 handleUserUpdated(user) 18 19 case "organization.created": 20 // Handle new organization creation 21 organization := eventData["organization"].(map[string]interface{}) 22 handleOrganizationCreated(organization) 23 24 case "membership.created": 25 // Handle user joining organization 26 membership := eventData["membership"].(map[string]interface{}) 27 handleMembershipCreated(membership) 28 29 default: 30 fmt.Printf("Unhandled event type: %s\n", eventType) 31 } 32 } 33 34 func handleUserCreated(user, organization map[string]interface{}) { 35 // Use case: Sync new user to your database, send welcome email, set up user workspace 36 fmt.Printf("New user created: %s in org: %s\n", 37 user["email"], organization["display_name"]) 38 39 // Sync to your database 40 syncUserToDatabase(user, organization) 41 42 // Send welcome email 43 sendWelcomeEmail(user["email"].(string), user["first_name"].(string)) 44 45 // Set up user workspace or default settings 46 setupUserDefaults(user["id"].(string), organization["id"].(string)) 47 } ``` * Java Process webhook events ```java 1 private void processWebhookEvent(Map event) { 2 String eventType = (String) event.get("type"); 3 Map eventData = (Map) event.get("data"); 4 5 System.out.println("Processing event: " + eventType); 6 7 switch (eventType) { 8 case "user.created": 9 // Handle new user registration 10 Map user = (Map) eventData.get("user"); 11 Map organization = (Map) eventData.get("organization"); 12 handleUserCreated(user, organization); 13 break; 14 15 case "user.updated": 16 // Handle user profile updates 17 handleUserUpdated((Map) eventData.get("user")); 18 break; 19 20 case "organization.created": 21 // Handle new organization creation 22 handleOrganizationCreated((Map) eventData.get("organization")); 23 break; 24 25 case "membership.created": 26 // Handle user joining organization 27 handleMembershipCreated((Map) eventData.get("membership")); 28 break; 29 30 default: 31 System.out.println("Unhandled event type: " + eventType); 32 } 33 } 34 35 private void handleUserCreated(Map user, Map organization) { 36 // Use case: Sync new user to your database, send welcome email, set up user workspace 37 System.out.println("New user created: " + user.get("email") + 38 " in org: " + organization.get("display_name")); 39 40 // Sync to your database 41 syncUserToDatabase(user, organization); 42 43 // Send welcome email 44 sendWelcomeEmail((String) user.get("email"), (String) user.get("first_name")); 45 46 // Set up user workspace or default settings 47 setupUserDefaults((String) user.get("id"), (String) organization.get("id")); 48 } ``` 3. ### Verify with the three webhook headers [Section titled “Verify with the three webhook headers”](#verify-with-the-three-webhook-headers) Call the SDK verify method **before** you parse JSON. Pass the dashboard signing secret (`whsec_…`), the raw body, and these headers: | Header | Role | | ------------------- | ---------------------------------------------------------------------------------- | | `webhook-id` | Event id in the HMAC | | `webhook-timestamp` | Unix seconds. The SDK rejects timestamps more than 5 minutes in the past or future | | `webhook-signature` | Space-separated `v1,` values | | Language | Method | | -------- | ------------------------------------------------------------------------- | | Node.js | `scalekit.verifyWebhookPayload(secret, headers, payload)` | | Python | `scalekit_client.verify_webhook_payload(secret, headers, payload)` | | Go | `scalekitClient.VerifyWebhookPayload(secret, headers, payload)` | | Java | `scalekitClient.webhook().verifyWebhookPayload(secret, headers, payload)` | Node, Python, and Java throw when the signature is invalid. Go returns `(false, error)`. There is no `webhooks.verifySignature` method and no `scalekit-signature` header. Verify before you trust the payload A forged POST can create or delete users in your app. Verify first. Sign the exact bytes Scalekit posted. `JSON.parse` / `request.get_json()` / `req.json()` change whitespace and fail the HMAC. Use `express.raw`, `request.get_data()`, or `io.ReadAll`. ## Respond to webhook event [Section titled “Respond to webhook event”](#respond-to-webhook-event) Scalekit expects specific HTTP status codes in response to webhook deliveries. Return appropriate status codes to control retry behavior. 1. ### Return success responses [Section titled “Return success responses”](#return-success-responses) Return success status codes when webhooks are processed successfully. | Status Code | Description | | ------------------------- | -------------------------------------------- | | `200 OK` | Webhook processed successfully | | `201 Created` Recommended | Webhook processed and resource created | | `202 Accepted` | Webhook accepted for asynchronous processing | 2. ### Handle error responses [Section titled “Handle error responses”](#handle-error-responses) Return error status codes to indicate processing failures. | Status Code | Description | | --------------------------- | ------------------------------------ | | `400 Bad Request` | Invalid payload or malformed request | | `401 Unauthorized` | Invalid webhook signature | | `403 Forbidden` | Webhook not authorized | | `422 Unprocessable Entity` | Valid request but cannot process | | `500 Internal Server Error` | Server error during processing | Retry schedule Scalekit retries failed webhooks automatically using exponential backoff. Return appropriate error codes to avoid unnecessary retries. * **Initial retry**: Immediately after failure * **Subsequent retries**: 5 seconds, 30 seconds, 2 minutes, 5 minutes, 15 minutes * **Maximum attempts**: 6 total attempts over approximately 22 minutes * **Final failure**: Webhook marked as failed after all retries exhausted Webhook failures are logged in your Scalekit dashboard for monitoring and debugging. ## Testing webhooks [Section titled “Testing webhooks”](#testing-webhooks) Test your webhook implementation locally before deploying to production. Use **ngrok** to expose your local development server for webhook testing. Set up local webhook testing ```bash 1 # Install ngrok 2 npm install -g ngrok 3 4 # Start your local server 5 npm run dev 6 7 # In another terminal, expose your local server 8 ngrok http 3000 9 10 # Use the ngrok URL in your Scalekit dashboard 11 # Example: https://abc123.ngrok.io/webhooks/scalekit ``` ## Common webhook use cases [Section titled “Common webhook use cases”](#common-webhook-use-cases) Webhooks enable common integration patterns: * **User lifecycle management**: Sync user data across systems, provision accounts in downstream services, and trigger onboarding workflows when users sign up or update their profiles * **Organization and membership management**: Set up workspaces when organizations are created, update user access when they join or leave organizations, and provision organization-specific resources * **Authentication monitoring**: Track login patterns, update last-seen timestamps, and trigger security alerts for suspicious activity ## Webhook event reference [Section titled “Webhook event reference”](#webhook-event-reference) You now have a complete webhook implementation that can reliably process authentication events from Scalekit. Consider these additional improvements: [Organization events](/apis/#webhook/organizationcreated) [User events](/apis/#webhook/usersignup) [Directory events](/apis/#webhook/organizationdirectoryenabled) [SSO connection events](/apis/#webhook/organizationssocreated) [Role events](/apis/#webhook/rolecreated) [Permission events](/apis/#webhook/permissiondeleted) --- # DOCUMENT BOUNDARY --- # Intercept authentication flows > Apply decision checks at key points in the authentication flow Execute custom business logic during sign-up or login processes. For example, you can integrate with external systems to validate user existence before allowing login, or prevent sign-ups originating from suspicious IP addresses. Scalekit calls your application at key trigger points during authentication flows and waits for an ALLOW or DENY response to determine whether to continue with the authentication process. For example, one trigger point occurs immediately before a user signs up for your application. We’ll explore more trigger points throughout this guide. ## Implement interceptors [Section titled “Implement interceptors”](#implement-interceptors) You can define interceptors at several trigger points during authentication flows. | Trigger point | When it runs | | ---------------------- | --------------------------------------------------------------------- | | Pre-signup | Before a user creates a new organization | | Pre-session creation | Before session tokens are issued for a user | | Pre-user invitation | Before an invitation is created or sent for a new organization member | | Pre-M2M token creation | Before issuing a machine-to-machine access token | At each trigger point, Scalekit sends a POST request to your interceptor endpoint with the relevant details needed to process the request. 1. #### Verify the interceptor request [Section titled “Verify the interceptor request”](#verify-the-interceptor-request) Create an HTTPS endpoint that receives and verifies POST requests from Scalekit. This critical security step ensures requests are authentic and haven’t been tampered with. * Node.js Express.js - Verify request signature ```javascript 1 // Security: ALWAYS verify requests are from Scalekit before processing 2 // This prevents unauthorized parties from triggering your interceptor logic 3 4 app.post('/auth/interceptors/pre-signup', async (req, res) => { 5 try { 6 // Parse the request payload and headers 7 const event = await req.json(); 8 const headers = req.headers; 9 10 // Get the signing secret from Scalekit dashboard > Interceptors tab 11 // Store this securely in environment variables 12 const interceptorSecret = process.env.SCALEKIT_INTERCEPTOR_SECRET; 13 14 // Initialize Scalekit client (reference installation guide for setup) 15 const scalekit = new ScalekitClient( 16 process.env.SCALEKIT_ENVIRONMENT_URL, 17 process.env.SCALEKIT_CLIENT_ID, 18 process.env.SCALEKIT_CLIENT_SECRET 19 ); 20 21 // Verify the interceptor payload signature 22 // This confirms the request is from Scalekit and hasn't been tampered with 23 await scalekit.verifyInterceptorPayload(interceptorSecret, headers, event); 24 25 // ✓ Request verified - proceed to business logic (next step) 26 27 } catch (error) { 28 console.error('Interceptor verification failed:', error); 29 // DENY on verification failures to fail securely 30 return res.status(200).json({ 31 decision: 'DENY', 32 error: { 33 message: 'Unable to process request. Please try again later.' 34 } 35 }); 36 } 37 }); ``` * Python Flask - Verify request signature ```python 1 # Security: ALWAYS verify requests are from Scalekit before processing 2 # This prevents unauthorized parties from triggering your interceptor logic 3 4 from flask import Flask, request, jsonify 5 import os 6 7 app = Flask(__name__) 8 9 @app.route('/auth/interceptors/pre-signup', methods=['POST']) 10 def interceptor_pre_signup(): 11 try: 12 # Parse the request payload and headers 13 event = request.get_json() 14 body = request.get_data() 15 16 # Get the signing secret from Scalekit dashboard > Interceptors tab 17 # Store this securely in environment variables 18 interceptor_secret = os.getenv('SCALEKIT_INTERCEPTOR_SECRET') 19 20 # Extract headers for verification 21 headers = { 22 'interceptor-id': request.headers.get('interceptor-id'), 23 'interceptor-signature': request.headers.get('interceptor-signature'), 24 'interceptor-timestamp': request.headers.get('interceptor-timestamp') 25 } 26 27 # Initialize Scalekit client (reference installation guide for setup) 28 scalekit_client = ScalekitClient( 29 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 30 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 31 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 32 ) 33 34 # Verify the interceptor payload signature 35 # This confirms the request is from Scalekit and hasn't been tampered with 36 is_valid = scalekit_client.verify_interceptor_payload( 37 secret=interceptor_secret, 38 headers=headers, 39 payload=body 40 ) 41 42 if not is_valid: 43 return jsonify({ 44 'decision': 'DENY', 45 'error': {'message': 'Invalid request signature'} 46 }), 200 47 48 # ✓ Request verified - proceed to business logic (next step) 49 50 except Exception as error: 51 print(f'Interceptor verification failed: {error}') 52 # DENY on verification failures to fail securely 53 return jsonify({ 54 'decision': 'DENY', 55 'error': { 56 'message': 'Unable to process request. Please try again later.' 57 } 58 }), 200 ``` * Go Gin - Verify request signature ```go 1 // Security: ALWAYS verify requests are from Scalekit before processing 2 // This prevents unauthorized parties from triggering your interceptor logic 3 4 package main 5 6 import ( 7 "io" 8 "log" 9 "net/http" 10 "os" 11 12 "github.com/gin-gonic/gin" 13 ) 14 15 type InterceptorResponse struct { 16 Decision string `json:"decision"` 17 Error *InterceptorError `json:"error,omitempty"` 18 } 19 20 type InterceptorError struct { 21 Message string `json:"message"` 22 } 23 24 func interceptorPreSignup(c *gin.Context) { 25 // Parse the request payload 26 bodyBytes, err := io.ReadAll(c.Request.Body) 27 if err != nil { 28 c.JSON(http.StatusOK, InterceptorResponse{ 29 Decision: "DENY", 30 Error: &InterceptorError{Message: "Unable to read request"}, 31 }) 32 return 33 } 34 35 // Get the signing secret from Scalekit dashboard > Interceptors tab 36 // Store this securely in environment variables 37 interceptorSecret := os.Getenv("SCALEKIT_INTERCEPTOR_SECRET") 38 39 // Extract headers for verification 40 headers := map[string]string{ 41 "interceptor-id": c.GetHeader("interceptor-id"), 42 "interceptor-signature": c.GetHeader("interceptor-signature"), 43 "interceptor-timestamp": c.GetHeader("interceptor-timestamp"), 44 } 45 46 // Initialize Scalekit client (reference installation guide for setup) 47 scalekitClient := scalekit.NewScalekitClient( 48 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 49 os.Getenv("SCALEKIT_CLIENT_ID"), 50 os.Getenv("SCALEKIT_CLIENT_SECRET"), 51 ) 52 53 // Verify the interceptor payload signature 54 // This confirms the request is from Scalekit and hasn't been tampered with 55 _, err = scalekitClient.VerifyInterceptorPayload( 56 interceptorSecret, 57 headers, 58 bodyBytes, 59 ) 60 if err != nil { 61 log.Printf("Interceptor verification failed: %v", err) 62 // DENY on verification failures to fail securely 63 c.JSON(http.StatusOK, InterceptorResponse{ 64 Decision: "DENY", 65 Error: &InterceptorError{Message: "Invalid request signature"}, 66 }) 67 return 68 } 69 70 // ✓ Request verified - proceed to business logic (next step) 71 } ``` * Java Spring Boot - Verify request signature ```java 1 // Security: ALWAYS verify requests are from Scalekit before processing 2 // This prevents unauthorized parties from triggering your interceptor logic 3 4 package com.example.auth; 5 6 import org.springframework.http.ResponseEntity; 7 import org.springframework.web.bind.annotation.*; 8 9 import java.util.Map; 10 11 @RestController 12 @RequestMapping("/auth/interceptors") 13 public class InterceptorController { 14 15 @PostMapping("/pre-signup") 16 public ResponseEntity> preSignupInterceptor( 17 @RequestBody String body, 18 @RequestHeader Map headers 19 ) { 20 try { 21 // Get the signing secret from Scalekit dashboard > Interceptors tab 22 // Store this securely in environment variables 23 String interceptorSecret = System.getenv("SCALEKIT_INTERCEPTOR_SECRET"); 24 25 // Initialize Scalekit client (reference installation guide for setup) 26 ScalekitClient scalekitClient = new ScalekitClient( 27 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 28 System.getenv("SCALEKIT_CLIENT_ID"), 29 System.getenv("SCALEKIT_CLIENT_SECRET") 30 ); 31 32 // Verify the interceptor payload signature 33 // This confirms the request is from Scalekit and hasn't been tampered with 34 boolean valid = scalekitClient.interceptor() 35 .verifyInterceptorPayload(interceptorSecret, headers, body.getBytes()); 36 37 if (!valid) { 38 // DENY on invalid signatures 39 return ResponseEntity.ok(Map.of( 40 "decision", "DENY", 41 "error", Map.of("message", "Invalid request signature") 42 )); 43 } 44 45 // ✓ Request verified - proceed to business logic (next step) 46 47 } catch (Exception error) { 48 System.err.println("Interceptor verification failed: " + error.getMessage()); 49 // DENY on verification failures to fail securely 50 return ResponseEntity.ok(Map.of( 51 "decision", "DENY", 52 "error", Map.of( 53 "message", "Unable to process request. Please try again later." 54 ) 55 )); 56 } 57 } 58 } ``` 2. #### Implement business logic and respond [Section titled “Implement business logic and respond”](#implement-business-logic-and-respond) After verification, extract data from the payload, apply your custom validation logic, and return either ALLOW or DENY to control the authentication flow. * Node.js Express.js - Business logic and response ```javascript 1 // Use case: Apply custom validation rules before allowing authentication 2 // Examples: email domain validation, IP filtering, database checks, etc. 3 4 app.post('/auth/interceptors/pre-signup', async (req, res) => { 5 try { 6 // ... (verification code from Step 1) 7 8 // Extract data from the verified payload 9 const { interceptor_context, data } = event; 10 const userEmail = interceptor_context?.user_email || data?.user?.email; 11 12 // Implement your business logic 13 // Example: Validate email domain against an allowlist 14 const emailDomain = userEmail?.split('@')[1]; 15 const allowedDomains = ['company.com', 'example.com']; 16 17 if (!allowedDomains.includes(emailDomain)) { 18 // DENY: Block the authentication flow 19 return res.status(200).json({ 20 decision: 'DENY', 21 error: { 22 message: 'Sign-ups from this email domain are not permitted.' 23 } 24 }); 25 } 26 27 // Optional: Log successful validations for audit purposes 28 console.log(`Allowed signup for ${userEmail}`); 29 30 // ALLOW: Permit the authentication flow to continue 31 return res.status(200).json({ 32 decision: 'ALLOW' 33 }); 34 35 } catch (error) { 36 console.error('Interceptor error:', error); 37 return res.status(200).json({ 38 decision: 'DENY', 39 error: { 40 message: 'Unable to process request. Please try again later.' 41 } 42 }); 43 } 44 }); ``` * Python Flask - Business logic and response ```python 1 # Use case: Apply custom validation rules before allowing authentication 2 # Examples: email domain validation, IP filtering, database checks, etc. 3 4 @app.route('/auth/interceptors/pre-signup', methods=['POST']) 5 def interceptor_pre_signup(): 6 try: 7 # ... (verification code from Step 1) 8 9 # Extract data from the verified payload 10 interceptor_context = event.get('interceptor_context', {}) 11 data = event.get('data', {}) 12 user_email = interceptor_context.get('user_email') or data.get('user', {}).get('email') 13 14 # Implement your business logic 15 # Example: Validate email domain against an allowlist 16 email_domain = user_email.split('@')[1] if user_email else '' 17 allowed_domains = ['company.com', 'example.com'] 18 19 if email_domain not in allowed_domains: 20 # DENY: Block the authentication flow 21 return jsonify({ 22 'decision': 'DENY', 23 'error': { 24 'message': 'Sign-ups from this email domain are not permitted.' 25 } 26 }), 200 27 28 # Optional: Log successful validations for audit purposes 29 print(f'Allowed signup for {user_email}') 30 31 # ALLOW: Permit the authentication flow to continue 32 return jsonify({ 33 'decision': 'ALLOW' 34 }), 200 35 36 except Exception as error: 37 print(f'Interceptor error: {error}') 38 return jsonify({ 39 'decision': 'DENY', 40 'error': { 41 'message': 'Unable to process request. Please try again later.' 42 } 43 }), 200 ``` * Go Gin - Business logic and response ```go 1 // Use case: Apply custom validation rules before allowing authentication 2 // Examples: email domain validation, IP filtering, database checks, etc. 3 4 package main 5 6 import ( 7 "encoding/json" 8 "strings" 9 ) 10 11 type InterceptorEvent struct { 12 InterceptorContext struct { 13 UserEmail string `json:"user_email"` 14 } `json:"interceptor_context"` 15 Data struct { 16 User struct { 17 Email string `json:"email"` 18 } `json:"user"` 19 } `json:"data"` 20 } 21 22 func interceptorPreSignup(c *gin.Context) { 23 // ... (verification code from Step 1) 24 25 // Extract data from the verified payload 26 var event InterceptorEvent 27 if err := json.Unmarshal(bodyBytes, &event); err != nil { 28 c.JSON(http.StatusOK, InterceptorResponse{ 29 Decision: "DENY", 30 Error: &InterceptorError{Message: "Invalid request format"}, 31 }) 32 return 33 } 34 35 userEmail := event.InterceptorContext.UserEmail 36 if userEmail == "" { 37 userEmail = event.Data.User.Email 38 } 39 40 // Implement your business logic 41 // Example: Validate email domain against an allowlist 42 parts := strings.Split(userEmail, "@") 43 if len(parts) != 2 { 44 c.JSON(http.StatusOK, InterceptorResponse{ 45 Decision: "DENY", 46 Error: &InterceptorError{Message: "Invalid email address"}, 47 }) 48 return 49 } 50 51 emailDomain := parts[1] 52 allowedDomains := []string{"company.com", "example.com"} 53 54 allowed := false 55 for _, domain := range allowedDomains { 56 if emailDomain == domain { 57 allowed = true 58 break 59 } 60 } 61 62 if !allowed { 63 // DENY: Block the authentication flow 64 c.JSON(http.StatusOK, InterceptorResponse{ 65 Decision: "DENY", 66 Error: &InterceptorError{ 67 Message: "Sign-ups from this email domain are not permitted.", 68 }, 69 }) 70 return 71 } 72 73 // Optional: Log successful validations for audit purposes 74 log.Printf("Allowed signup for %s", userEmail) 75 76 // ALLOW: Permit the authentication flow to continue 77 c.JSON(http.StatusOK, InterceptorResponse{ 78 Decision: "ALLOW", 79 }) 80 } ``` * Java Spring Boot - Business logic and response ```java 1 // Use case: Apply custom validation rules before allowing authentication 2 // Examples: email domain validation, IP filtering, database checks, etc. 3 4 package com.example.auth; 5 6 import com.fasterxml.jackson.databind.JsonNode; 7 import com.fasterxml.jackson.databind.ObjectMapper; 8 9 import java.util.Arrays; 10 import java.util.List; 11 12 @PostMapping("/pre-signup") 13 public ResponseEntity> preSignupInterceptor( 14 @RequestBody String body, 15 @RequestHeader Map headers 16 ) { 17 try { 18 // ... (verification code from Step 1) 19 20 // Extract data from the verified payload 21 ObjectMapper mapper = new ObjectMapper(); 22 JsonNode event = mapper.readTree(body); 23 JsonNode interceptorContext = event.get("interceptor_context"); 24 JsonNode data = event.get("data"); 25 26 String userEmail = null; 27 if (interceptorContext != null && interceptorContext.has("user_email")) { 28 userEmail = interceptorContext.get("user_email").asText(); 29 } else if (data != null && data.has("user")) { 30 userEmail = data.get("user").get("email").asText(); 31 } 32 33 // Implement your business logic 34 // Example: Validate email domain against an allowlist 35 if (userEmail != null && userEmail.contains("@")) { 36 String emailDomain = userEmail.split("@")[1]; 37 List allowedDomains = Arrays.asList("company.com", "example.com"); 38 39 if (!allowedDomains.contains(emailDomain)) { 40 // DENY: Block the authentication flow 41 return ResponseEntity.ok(Map.of( 42 "decision", "DENY", 43 "error", Map.of( 44 "message", "Sign-ups from this email domain are not permitted." 45 ) 46 )); 47 } 48 } 49 50 // Optional: Log successful validations for audit purposes 51 System.out.println("Allowed signup for " + userEmail); 52 53 // ALLOW: Permit the authentication flow to continue 54 return ResponseEntity.ok(Map.of( 55 "decision", "ALLOW" 56 )); 57 58 } catch (Exception error) { 59 System.err.println("Interceptor error: " + error.getMessage()); 60 return ResponseEntity.ok(Map.of( 61 "decision", "DENY", 62 "error", Map.of( 63 "message", "Unable to process request. Please try again later." 64 ) 65 )); 66 } 67 } ``` 3. #### Register the interceptor in Scalekit dashboard [Section titled “Register the interceptor in Scalekit dashboard”](#register-the-interceptor-in-scalekit-dashboard) Configure your interceptor by specifying the trigger point, endpoint URL, timeout settings, and fallback behavior. In the Scalekit dashboard, navigate to the **Interceptors** tab to register your endpoint. ![Interceptors settings in the Scalekit dashboard](/.netlify/images?url=_astro%2Fadd-interceptor-page.UBrvBruB.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) * Enter a descriptive name, choose a trigger point, and provide the HTTPS endpoint that will receive POST requests * Set the timeout for your app’s response (recommended: 3-5 seconds) * Choose the fallback behavior if your app fails or times out (allow or block the flow) * Click **Create** * Toggle **Enable** to activate the interceptor 4. #### Test the interceptor [Section titled “Test the interceptor”](#test-the-interceptor) Use the Test tab in the Scalekit dashboard to verify your implementation before enabling it in production. * Open the **Test** tab on the Interceptors page * The left panel shows the request body sent to your endpoint * Click **Send request** to test your interceptor * The right panel shows your application’s response * Verify your endpoint returns the expected ALLOW or DENY decision ![Interceptor test tab example](/.netlify/images?url=_astro%2Ftest-example.xdLJLh_5.png\&w=2970\&h=1643\&dpl=6aaa70ad2ea7b40008ad2afd) 5. #### View interceptor request logs [Section titled “View interceptor request logs”](#view-interceptor-request-logs) Scalekit keeps a log of every interceptor request sent to your app and the response it returned. Use these logs to debug and troubleshoot issues. ![Interceptor logs in the dashboard](/.netlify/images?url=_astro%2Flogging.DSZdvTsn.png\&w=3024\&h=1705\&dpl=6aaa70ad2ea7b40008ad2afd) Requests and responses generated by the “Test” button are not logged. This keeps production logs free of test data. ## Interceptor examples [Section titled “Interceptor examples”](#interceptor-examples) ### Block signups from restricted IP addresses [Section titled “Block signups from restricted IP addresses”](#block-signups-from-restricted-ip-addresses) Prevent new user signups from specific IP addresses or geographic regions. The request includes `ip_address` and `region` (country code) in `interceptor_context`. * Node.js Express.js ```javascript 1 app.post('/auth/interceptor/pre-signup', async (req, res) => { 2 const { interceptor_context } = req.body; 3 4 // Extract IP address and region from the request 5 const ipAddress = interceptor_context.ip_address; 6 const region = interceptor_context.region; 7 8 // Define your IP blocklist (you can also check against a database) 9 const blockedIPs = ['203.0.113.24', '198.51.100.42']; 10 const blockedRegions = ['XX', 'YY']; // Example: blocked region codes 11 12 // Check if IP is blocked 13 if (blockedIPs.includes(ipAddress)) { 14 return res.json({ 15 decision: 'DENY', 16 error: { 17 message: 'Signups from your IP address are not allowed due to security policy' 18 } 19 }); 20 } 21 22 // Check if region is blocked 23 if (blockedRegions.includes(region)) { 24 return res.json({ 25 decision: 'DENY', 26 error: { 27 message: 'Signups from your location are restricted due to compliance requirements' 28 } 29 }); 30 } 31 32 // Allow signup to proceed 33 return res.json({ 34 decision: 'ALLOW' 35 }); 36 }); ``` * Python Flask ```python 1 @app.post('/auth/interceptor/pre-signup') 2 async def pre_signup(request: Request): 3 body = await request.json() 4 interceptor_context = body['interceptor_context'] 5 6 # Extract IP address and region from the request 7 ip_address = interceptor_context['ip_address'] 8 region = interceptor_context['region'] 9 10 # Define your IP blocklist (you can also check against a database) 11 blocked_ips = ['203.0.113.24', '198.51.100.42'] 12 blocked_regions = ['XX', 'YY'] # Example: blocked region codes 13 14 # Check if IP is blocked 15 if ip_address in blocked_ips: 16 return { 17 'decision': 'DENY', 18 'error': { 19 'message': 'Signups from your IP address are not allowed due to security policy' 20 } 21 } 22 23 # Check if region is blocked 24 if region in blocked_regions: 25 return { 26 'decision': 'DENY', 27 'error': { 28 'message': 'Signups from your location are restricted due to compliance requirements' 29 } 30 } 31 32 # Allow signup to proceed 33 return {'decision': 'ALLOW'} ``` ### Modify claims in session tokens [Section titled “Modify claims in session tokens”](#modify-claims-in-session-tokens) To include additional custom claims in the access token, use the `PRE_SESSION_CREATION` interceptor. This interceptor makes an API call to your configured endpoint with user and organization data from Scalekit. You can respond with the format below, and the claims are included in the access token under the `custom_claims` key. This interceptor fires on every path that creates a new session token: standard login and organization switch. If you need custom scope strings validated directly by your resource server (for example, Spring Security’s `@PreAuthorize`), use [native custom scopes and permissions](/authenticate/authz/implement-access-control/) instead — `custom_claims` do not appear in the `scope` claim. * Node.js Express.js ```javascript 1 app.post('/auth/interceptor/pre-session-creation', async (req, res) => { 2 const { interceptor_context } = req.body; 3 4 const userId = interceptor_context.user_id; 5 const organizationId = interceptor_context.organization_id; 6 7 // Fetch user subscription and permissions from your database 8 const userMetadata = await fetchUserMetadata(userId, organizationId); 9 10 // Build custom claims based on your business logic 11 const customClaims = { 12 plan: userMetadata.subscription.plan, // 'free', 'pro', 'enterprise' 13 plan_expires_at: userMetadata.subscription.expiresAt, 14 features: userMetadata.features, // ['analytics', 'api_access', 'advanced_reports'] 15 org_role: userMetadata.organizationRole, // 'admin', 'member', 'viewer' 16 department: userMetadata.department, 17 cost_center: userMetadata.costCenter 18 }; 19 20 // Return ALLOW decision with custom claims 21 return res.json({ 22 decision: 'ALLOW', 23 response: { 24 claims: customClaims 25 } 26 }); 27 }); ``` * Python Flask ```python 1 @app.post('/auth/interceptor/pre-session-creation') 2 async def pre_session_creation(request: Request): 3 body = await request.json() 4 interceptor_context = body['interceptor_context'] 5 6 user_id = interceptor_context['user_id'] 7 organization_id = interceptor_context['organization_id'] 8 9 # Fetch user subscription and permissions from your database 10 user_metadata = await fetch_user_metadata(user_id, organization_id) 11 12 # Build custom claims based on your business logic 13 custom_claims = { 14 'plan': user_metadata['subscription']['plan'], 15 'plan_expires_at': user_metadata['subscription']['expires_at'], 16 'features': user_metadata['features'], 17 'org_role': user_metadata['organization_role'], 18 'department': user_metadata['department'], 19 'cost_center': user_metadata['cost_center'] 20 } 21 22 # Return ALLOW decision with custom claims 23 return { 24 'decision': 'ALLOW', 25 'response': { 26 'claims': custom_claims 27 } 28 } ``` After the interceptor returns custom claims, Scalekit includes them in the access token. When you decode the access token, it contains your custom claims in the `custom_claims` object along with standard JWT fields: Decoded access token ```diff { "aud": [ "prd_skc_96736847635480854" ], "client_id": "prd_skc_96736847635480854", "custom_claims": { "cost_center": "R&D-001", "department": "Engineering", "features": [ "analytics", "api_access", "advanced_reports" + ], "org_role": "admin", "plan": "pro", "plan_expires_at": "2025-12-31T23:59:59Z" + }, "exp": 1767964824, "iat": 1767964524, "iss": "https://auth.coffeedesk.app", "jti": "tkn_107201921814692618", "nbf": 1767964524, "oid": "org_97926637244383515", "permissions": [ "data:read", "data:write", "organization:settings" ], "roles": [ "admin" ], "sid": "ses_107201917586768386", "sub": "usr_97931091561677319", "xoid": "wspace_97926637244383515", "xuid": "0a749c69-1153-4a8b-b56d-94ebde9da8de" } ``` ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) ### Provision a user into an existing organization [Section titled “Provision a user into an existing organization”](#provision-a-user-into-an-existing-organization) Use the **Pre-signup** interceptor to provision a user into an existing organization instead of creating a new one during signup. This is useful when you want users from specific email domains to always join a pre-defined organization, avoiding duplicate organization creation. In the following example, the B2B application provisions users into an existing organization based on their email domain. If no matching domain is found, the signup flow falls back to the default behavior and creates a new organization. * Node.js Express.js ```javascript 1 app.post('/auth/interceptors/pre-signup', async (req, res) => { 2 const { interceptor_context } = req.body; 3 4 // Email attempting to sign up 5 const userEmail = interceptor_context.user_email; 6 const emailDomain = userEmail?.split('@')[1]; 7 8 // Map email domains to organizations 9 const domainOrgMappings = [ 10 { 11 domain: 'acmecorp.com', 12 organization_id: 'org_123456789', 13 external_organization_id: 'ext_acmecorp_123' 14 }, 15 { 16 domain: 'megacorp.com', 17 organization_id: 'org_987654321', 18 external_organization_id: 'ext_megacorp_456' 19 } 20 ]; 21 22 const match = domainOrgMappings.find( 23 (entry) => entry.domain === emailDomain 24 ); 25 26 // Fallback to default signup behavior 27 if (!match) { 28 return res.json({ decision: 'ALLOW' }); 29 } 30 31 return res.json({ 32 decision: 'ALLOW', 33 response: { 34 create_organization_membership: { 35 // Either external_organization_id or organization_id is required 36 organization_id: match.organization_id, 37 external_organization_id: match.external_organization_id 38 } 39 } 40 }); 41 }); ``` * Python ```python 1 @app.post('/auth/interceptors/pre-signup') 2 def pre_signup(): 3 body = request.get_json() 4 5 interceptor_context = body.get('interceptor_context', {}) 6 7 # Email attempting to sign up 8 user_email = interceptor_context.get('user_email') 9 email_domain = user_email.split('@')[1] if user_email else None 10 11 # Map email domains to organizations 12 domain_org_mappings = [ 13 { 14 domain: 'acmecorp.com', 15 organization_id: 'org_123456789', 16 external_organization_id: 'ext_acmecorp_123' 17 }, 18 { 19 domain: 'megacorp.com', 20 organization_id: 'org_987654321', 21 external_organization_id: 'ext_megacorp_456' 22 } 23 ] 24 25 match = next( 26 (entry for entry in domain_org_mappings if entry['domain'] == email_domain), 27 None 28 ) 29 30 # Fallback to default signup behavior 31 if not match: 32 return {'decision': 'ALLOW'} 33 34 return { 35 'decision': 'ALLOW', 36 'response': { 37 'create_organization_membership': { 38 # Either external_organization_id or organization_id is required 39 'organization_id': match.get('organization_id'), 40 'external_organization_id': match.get('external_organization_id') 41 } 42 } 43 } ``` --- # DOCUMENT BOUNDARY --- # Add OAuth 2.0 to your APIs > Secure your APIs in minutes with OAuth 2.0 client credentials, scoped access, and JWT validation using Scalekit APIs let your customers, partners, and external systems interact with your application and its data. You need authentication to ensure only authorized clients can consume your APIs. Scalekit helps you add OAuth 2.0-based client-credentials authentication to your API endpoints. If you are new to JWT-based API authentication, read the cookbook **[M2M JWT verification with JWKS and OAuth scopes](/cookbooks/m2m-jwks-and-oauth-scopes/)** for foundational context before following the steps below. Here’s how it works: 1. ## Installation [Section titled “Installation”](#installation) Scalekit becomes the authorization server for your APIs. Using Scalekit provides necessary methods to register and authenticate API clients. ```sh pip install scalekit-sdk-python ``` Alternatively, you can use the [REST APIs directly](/apis/#tag/api-auth). 2. ## Enable API client registration for your customers [Section titled “Enable API client registration for your customers”](#enable-api-client-registration-for-your-customers) Allow your customers to register their applications as API clients. This process generates unique credentials that they can use to authenticate their application when interacting with your API. Scalekit will return a client ID and secret that you can show to your customers to integrate their application with your API. * An Organization ID identifies your customer, and multiple API clients can be registered for the same organization. * The `POST /organizations/{organization_id}/clients` endpoint creates a new API client for the organization. See [Scalekit API Authentication](/apis/#description/quickstart) to get the `` in case of HTTP requests. - cURL POST /organizations/{organization\_id}/clients ```bash # For authentication details, see: http://docs.scalekit.com/apis#description/authentication curl -L '/api/v1/organizations//clients' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "name": "GitHub Actions Deployment Service", # A descriptive name for the API client "description": "Service account for GitHub Actions to deploy applications to production", # A detailed explanation of the clients purpose and usage "custom_claims": [ # Key-value pairs that provide additional context about the client. Each claim must have a `key` and `value` field { "key": "github_repository", "value": "acmecorp/inventory-service" }, { "key": "environment", "value": "production_us" } ], "scopes": [ # List of permissions the client needs (e.g., ["deploy:applications", "read:deployments"]) "deploy:applications", "read:deployments" ], "audience": [ # List of API endpoints this client will access (e.g., ["deployment-api.acmecorp.com"]) "deployment-api.acmecorp.com" ], "expiry": 3600 # Token expiration time in seconds. Defaults to 3600 (1 hour) }' ``` - Python ```python 1 from scalekit.v1.clients.clients_pb2 import OrganizationClient 2 3 org_id = "" 4 5 api_client = OrganizationClient( 6 name="GitHub Actions Deployment Service", # A descriptive name for the API client 7 description="Service account for GitHub Actions to deploy applications to production", # A detailed explanation of the client's purpose and usage 8 custom_claims=[ # Key-value pairs that provide additional context about the client. Each claim must have a `key` and `value` field 9 { 10 "key": "github_repository", 11 "value": "acmecorp/inventory-service" 12 }, 13 { 14 "key": "environment", 15 "value": "production_us" 16 } 17 ], 18 scopes=["deploy:applications", "read:deployments"], # List of permissions the client needs 19 audience=["deployment-api.acmecorp.com"], # List of API endpoints this client will access 20 expiry=3600 # Token expiration time in seconds. Defaults to 3600 (1 hour) 21 ) 22 23 response = scalekit_client.m2m_client.create_organization_client( 24 organization_id=org_id, 25 m2m_client=api_client 26 ) 27 28 # Persist the generated credentials securely in your application 29 client_id = response.client.client_id 30 plain_secret = response.plain_secret ``` 3. ## API client requests Bearer access token for API authentication [Section titled “API client requests Bearer access token for API authentication”](#api-client-requests-bearer-access-token-for-api-authentication) API clients use the `client_id` and `client_secret` issued in the previous step to reach your Scalekit environment and get the access token. No action is needed by you in your API server. This section only demonstrates how API clients get the `access_token`. The client sends a POST request to the `/oauth/token` endpoint: * cURL POST /oauth/token ```sh 1 curl -X POST \ 2 "https:///oauth/token" \ 3 -H "Content-Type: application/x-www-form-urlencoded" \ 4 -d "grant_type=client_credentials" \ 5 -d "client_id=" \ 6 -d "client_secret=" \ ``` * Python ```python 1 client_id = "API_CLIENT_ID" 2 client_secret = "API_CLIENT_SECRET" 3 4 token_response = scalekit_client.generate_client_token( 5 client_id=client_id, 6 client_secret=client_secret 7 ) ``` Upon successful authentication, your Scalekit environment issues a JWT access token to the API client. Access token response ```json 1 { 2 "access_token":"", 3 "token_type":"Bearer", 4 "expires_in":86399, 5 // Same scopes that were granted during client registration 6 "scope":"deploy:applications read:deployments" 7 } ``` The client includes this access token in the `Authorization` header of subsequent requests to your API server. Your API server validates these tokens before granting access to resources. 4. ## Validate and authenticate API client’s access tokens [Section titled “Validate and authenticate API client’s access tokens”](#validate-and-authenticate-api-clients-access-tokens) Your API server must validate the incoming JWT access token to ensure the request originates from a trusted API client and that the token is legitimate. Validate the token in two steps: 1. **Retrieve the public key:** Fetch the appropriate public key from your Scalekit environment’s [JSON Web Key Set (JWKS)](/cookbooks/m2m-jwks-and-oauth-scopes/#jwks-and-scalekit-keys) at `https:///keys`. Use the `kid` (Key ID) from the JWT header to identify the correct key. Cache the key according to standard JWKS practices. * Node.js ```js import jwksClient from 'jwks-rsa'; const client = jwksClient({ jwksUri: `${process.env.SCALEKIT_ENVIRONMENT_URL}/keys`, cache: true }); async function getPublicKey(header: any): Promise { return new Promise((resolve, reject) => { client.getSigningKey(header.kid, (err, key) => { if (err) reject(err); else resolve(key.getPublicKey()); }); }); } ``` * Python ```py # This is automatically handled by Scalekit SDK ``` 2. **Verify the token signature:** Use the retrieved public key and a JWT library to verify the token’s signature and claims (like issuer, audience, and expiration). * Node.js ```js import jwt from 'jsonwebtoken'; async function verifyToken(token: string, publicKey: string) { try { const decoded = jwt.decode(token, { complete: true }); const verified = jwt.verify(token, publicKey, { algorithms: ['RS256'], complete: true }); return verified.payload; } catch (error) { throw new Error('Token verification failed'); } } ``` * Python ```py # Token from the incoming API request's authorization header token = token_response[""] claims = scalekit_client.validate_access_token_and_get_claims( token=token ) ``` Upon successful token verification, your API server gains confidence in the request’s legitimacy and can proceed to process the request, leveraging the authorization scopes embedded within the token. 5. ## Register API client’s scopes Optional [Section titled “Register API client’s scopes ”](#register-api-clients-scopes-) [OAuth scopes](/cookbooks/m2m-jwks-and-oauth-scopes/#oauth-scopes-for-machine-clients) are embedded in the access token and validated server-side using the Scalekit SDK. This ensures that API clients only access resources they’re authorized for, adding an extra layer of security. For example, you might create an API client for a customer’s deployment service with scopes like `deploy:applications` and `read:deployments`. * cURL Register an API client with specific scopes ```bash 1 curl -L 'https:///api/v1/organizations//clients' \ 2 -H 'Content-Type: application/json' \ 3 -H 'Authorization: Bearer ' \ 4 -d '{ 5 "name": "GitHub Actions Deployment Service", 6 "description": "Service account for GitHub Actions to deploy applications to production", 7 "scopes": [ 8 "deploy:applications", 9 "read:deployments" 10 ], 11 "expiry": 3600 12 }' ``` * Node.js Register an API client with specific scopes ```javascript 1 // Use case: Your customer requests API access for their deployment automation. 2 // You register an API client app with the appropriate scopes. 3 import { ScalekitClient } from '@scalekit-sdk/node'; 4 5 // Initialize Scalekit client (see installation guide for setup) 6 const scalekit = new ScalekitClient( 7 process.env.SCALEKIT_ENVIRONMENT_URL, 8 process.env.SCALEKIT_CLIENT_ID, 9 process.env.SCALEKIT_CLIENT_SECRET 10 ); 11 12 async function createAPIClient() { 13 try { 14 // Define API client details with scopes your customer's app needs 15 const clientDetails = { 16 name: 'GitHub Actions Deployment Service', 17 description: 'Service account for GitHub Actions to deploy applications to production', 18 scopes: ['deploy:applications', 'read:deployments'], 19 expiry: 3600, // Token expiry in seconds 20 }; 21 22 // API call to register the client 23 const response = await scalekit.m2m.createClient({ 24 organizationId: process.env.SCALEKIT_ORGANIZATION_ID, 25 client: clientDetails, 26 }); 27 28 // Response contains client details and the plain_secret (only returned once) 29 const clientId = response.client.client_id; 30 const plainSecret = response.plain_secret; 31 32 // Provide these credentials to your customer securely 33 console.log('Created API client:', clientId); 34 } catch (error) { 35 console.error('Error creating API client:', error); 36 } 37 } 38 39 createAPIClient(); ``` * Python Register an API client with specific scopes ```python 1 # Use case: Your customer requests API access for their deployment automation. 2 # You register an API client app with the appropriate scopes. 3 import os 4 from scalekit import ScalekitClient 5 6 # Initialize Scalekit client (see installation guide for setup) 7 scalekit_client = ScalekitClient( 8 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 9 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 10 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 11 ) 12 13 try: 14 # Define API client details with scopes your customer's app needs 15 from scalekit.v1.clients.clients_pb2 import OrganizationClient 16 17 client_details = OrganizationClient( 18 name="GitHub Actions Deployment Service", 19 description="Service account for GitHub Actions to deploy applications to production", 20 scopes=["deploy:applications", "read:deployments"], 21 expiry=3600 # Token expiry in seconds 22 ) 23 24 # API call to register the client 25 response = scalekit_client.m2m_client.create_organization_client( 26 organization_id=os.getenv("SCALEKIT_ORGANIZATION_ID"), 27 m2m_client=client_details 28 ) 29 30 # Response contains client details and the plain_secret (only returned once) 31 client_id = response.client.client_id 32 plain_secret = response.plain_secret 33 34 # Provide these credentials to your customer securely 35 print("Created API client:", client_id) 36 37 except Exception as e: 38 print("Error creating API client:", e) ``` The API returns a JSON object with two key parts: * `client.client_id` - The client identifier * `plain_secret` - The client secret (only returned once, never stored by Scalekit) Provide both values to your customer securely. Your customer will use these credentials in their application to authenticate with your API. The `plain_secret` is never shown again after creation. 6. ## Verify API client’s scopes [Section titled “Verify API client’s scopes”](#verify-api-clients-scopes) When your API server receives a request from an API client app, you must validate the scopes present in the access token provided in the `Authorization` header. The access token is a JSON Web Token (JWT). First, let’s look at the claims inside a decoded JWT payload. Scalekit encodes the granted scopes in the `scopes` field. Example decoded access token ```json { "client_id": "m2morg_69038819013296423", "exp": 1745305340, "iat": 1745218940, "iss": "", "jti": "tkn_69041163914445100", "nbf": 1745218940, "oid": "org_59615193906282635", "scopes": [ "deploy:applications", "read:deployments" ], "sub": "m2morg_69038819013296423" } ``` Your API server should inspect the `scopes` array in the token payload to authorize the requested operation. Here’s how you validate the token and check for a specific scope in your API server. * Node.js Example Express.js middleware for scope validation ```javascript 1 // Security: ALWAYS validate the access token on your server before trusting its claims. 2 // This prevents token forgery and ensures the token has not expired. 3 import { ScalekitClient } from '@scalekit-sdk/node'; 4 import jwt from 'jsonwebtoken'; 5 import jwksClient from 'jwks-rsa'; 6 7 const scalekit = new ScalekitClient( 8 process.env.SCALEKIT_ENVIRONMENT_URL, 9 process.env.SCALEKIT_CLIENT_ID, 10 process.env.SCALEKIT_CLIENT_SECRET 11 ); 12 13 // Setup JWKS client for token verification 14 const client = jwksClient({ 15 jwksUri: `${process.env.SCALEKIT_ENVIRONMENT_URL}/keys`, 16 cache: true 17 }); 18 19 async function getPublicKey(header) { 20 return new Promise((resolve, reject) => { 21 client.getSigningKey(header.kid, (err, key) => { 22 if (err) reject(err); 23 else resolve(key.getPublicKey()); 24 }); 25 }); 26 } 27 28 async function checkPermissions(req, res, next) { 29 const authHeader = req.headers.authorization; 30 if (!authHeader || !authHeader.startsWith('Bearer ')) { 31 return res.status(401).send('Unauthorized: Missing token'); 32 } 33 const token = authHeader.split(' ')[1]; 34 35 try { 36 // Decode to get the header with kid 37 const decoded = jwt.decode(token, { complete: true }); 38 const publicKey = await getPublicKey(decoded.header); 39 40 // Verify the token signature and claims 41 const verified = jwt.verify(token, publicKey, { 42 algorithms: ['RS256'], 43 complete: true 44 }); 45 46 const decodedToken = verified.payload; 47 48 // Check if the API client app has the required scope 49 const requiredScope = 'deploy:applications'; 50 if (decodedToken.scopes && decodedToken.scopes.includes(requiredScope)) { 51 // API client app has the required scope, proceed with the request 52 next(); 53 } else { 54 // API client app does not have the required scope 55 res.status(403).send('Forbidden: Insufficient permissions'); 56 } 57 } catch (error) { 58 // Token is invalid or expired 59 res.status(401).send('Unauthorized: Invalid token'); 60 } 61 } ``` * Python Example Flask decorator for scope validation ```python 1 # Security: ALWAYS validate the access token on your server before trusting its claims. 2 # This prevents token forgery and ensures the token has not expired. 3 import os 4 import functools 5 from scalekit import ScalekitClient 6 from flask import request, jsonify 7 8 # Initialize Scalekit client 9 scalekit_client = ScalekitClient( 10 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 11 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 12 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 13 ) 14 15 def check_permissions(required_scope): 16 def decorator(f): 17 @functools.wraps(f) 18 def decorated_function(*args, **kwargs): 19 auth_header = request.headers.get('Authorization') 20 if not auth_header or not auth_header.startswith('Bearer '): 21 return jsonify({"error": "Unauthorized: Missing token"}), 401 22 23 token = auth_header.split(' ')[1] 24 25 try: 26 # Validate the token using the Scalekit SDK 27 claims = scalekit_client.validate_access_token_and_get_claims(token=token) 28 29 # Check if the API client app has the required scope 30 if required_scope in claims.get('scopes', []): 31 # API client app has the required scope 32 return f(*args, **kwargs) 33 else: 34 # API client app does not have the required scope 35 return jsonify({"error": "Forbidden: Insufficient permissions"}), 403 36 except Exception as e: 37 # Token is invalid or expired 38 return jsonify({"error": "Unauthorized: Invalid token"}), 401 39 return decorated_function 40 return decorator 41 42 # Example usage in a Flask route 43 # @app.route('/deploy', methods=['POST']) 44 # @check_permissions('deploy:applications') 45 # def deploy_application(): 46 # return jsonify({"message": "Deployment successful"}) ``` --- # DOCUMENT BOUNDARY --- # API keys > Issue long-lived, revocable API keys scoped to organizations and users for programmatic access to your APIs When your customers integrate with your APIs — whether for CI/CD pipelines, partner integrations, or internal tooling — they need a straightforward way to authenticate. Scalekit API keys give you long-lived, revocable bearer credentials for organization-level or user-level access to your APIs. In this guide, you’ll learn how to create, validate, list, and revoke API keys using the Scalekit. 1. ## Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Initialize the Scalekit client with your environment credentials: * Node.js Express.js ```javascript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 3 const scalekit = new ScalekitClient( 4 process.env.SCALEKIT_ENVIRONMENT_URL, 5 process.env.SCALEKIT_CLIENT_ID, 6 process.env.SCALEKIT_CLIENT_SECRET 7 ); ``` * Python Flask ```python 1 import os 2 from scalekit import ScalekitClient 3 4 scalekit_client = ScalekitClient( 5 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 6 client_id=os.environ["SCALEKIT_CLIENT_ID"], 7 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 8 ) ``` * Go Gin ```go 1 import scalekit "github.com/scalekit-inc/scalekit-sdk-go/v2" 2 3 scalekitClient := scalekit.NewScalekitClient( 4 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 5 os.Getenv("SCALEKIT_CLIENT_ID"), 6 os.Getenv("SCALEKIT_CLIENT_SECRET"), 7 ) ``` * Java Spring Boot ```java 1 import com.scalekit.ScalekitClient; 2 3 ScalekitClient scalekitClient = new ScalekitClient( 4 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 5 System.getenv("SCALEKIT_CLIENT_ID"), 6 System.getenv("SCALEKIT_CLIENT_SECRET") 7 ); ``` 2. ## Create a token [Section titled “Create a token”](#create-a-token) To get started, create an API key scoped to an organization. You can optionally scope it to a specific user and attach custom metadata. ### Organization-scoped API key [Section titled “Organization-scoped API key”](#organization-scoped-api-key) **When to use**: Organization-scoped keys are for customers who need full access to all resources within their workspace or account. When they authenticate with the key, Scalekit validates it and confirms the organization context — your API then exposes all resources they own. **Example scenario**: You’re building a CRM like HubSpot. Your customer integrates with your API using an organization-scoped key. When they request contacts, tasks, or deals, the key validates successfully for their organization, and your API returns all resources in that workspace. This is the most common pattern for service-to-service integrations where the API key represents access on behalf of an entire organization. * Node.js ```javascript 1 try { 2 const response = await scalekit.token.createToken(organizationId, { 3 description: 'CI/CD pipeline token', 4 }); 5 6 // Store securely — this value cannot be retrieved again after creation 7 const opaqueToken = response.token; 8 // Stable identifier for management operations (format: apit_xxxxx) 9 const tokenId = response.tokenId; 10 } catch (error) { 11 console.error('Failed to create token:', error.message); 12 } ``` * Python ```python 1 try: 2 response = scalekit_client.tokens.create_token( 3 organization_id=organization_id, 4 description="CI/CD pipeline token", 5 ) 6 7 opaque_token = response.token # store this securely 8 token_id = response.token_id # format: apit_xxxxx 9 except Exception as e: 10 print(f"Failed to create token: {e}") ``` * Go ```go 1 response, err := scalekitClient.Token().CreateToken( 2 ctx, organizationId, scalekit.CreateTokenOptions{ 3 Description: "CI/CD pipeline token", 4 }, 5 ) 6 if err != nil { 7 log.Printf("Failed to create token: %v", err) 8 return 9 } 10 11 // Store securely — this value cannot be retrieved again after creation 12 opaqueToken := response.Token 13 // Stable identifier for management operations (format: apit_xxxxx) 14 tokenId := response.TokenId ``` * Java ```java 1 import com.scalekit.grpc.scalekit.v1.tokens.CreateTokenResponse; 2 3 try { 4 CreateTokenResponse response = scalekitClient.tokens().create(organizationId); 5 6 // Store securely — this value cannot be retrieved again after creation 7 String opaqueToken = response.getToken(); 8 // Stable identifier for management operations (format: apit_xxxxx) 9 String tokenId = response.getTokenId(); 10 } catch (Exception e) { 11 System.err.println("Failed to create token: " + e.getMessage()); 12 } ``` ### User-scoped API key [Section titled “User-scoped API key”](#user-scoped-api-key) **When to use**: User-scoped keys enable fine-grained data filtering based on who owns the key. Your API validates the key, receives the user context, and then exposes only data relevant to that user — enabling role-based filtering without additional database lookups. **Example scenario**: Your CRM has a `/tasks` endpoint. One customer gives their team member a user-scoped API key. When that person calls `/tasks`, the key validates for their organization *and* user, and your API returns only tasks assigned to them — not all tasks in the workspace. Another team member with a different key sees only their own tasks. User-scoped keys enable personal access tokens, per-user audit trails, and user-level rate limiting. You can also attach custom claims as key-value metadata. * Node.js ```javascript 1 try { 2 const userToken = await scalekit.token.createToken(organizationId, { 3 userId: 'usr_12345', 4 customClaims: { 5 team: 'engineering', 6 environment: 'production', 7 }, 8 description: 'Deployment service token', 9 }); 10 11 const opaqueToken = userToken.token; 12 const tokenId = userToken.tokenId; 13 } catch (error) { 14 console.error('Failed to create token:', error.message); 15 } ``` * Python ```python 1 try: 2 user_token = scalekit_client.tokens.create_token( 3 organization_id=organization_id, 4 user_id="usr_12345", 5 custom_claims={ 6 "team": "engineering", 7 "environment": "production", 8 }, 9 description="Deployment service token", 10 ) 11 12 opaque_token = user_token.token 13 token_id = user_token.token_id 14 except Exception as e: 15 print(f"Failed to create token: {e}") ``` * Go ```go 1 userToken, err := scalekitClient.Token().CreateToken( 2 ctx, organizationId, scalekit.CreateTokenOptions{ 3 UserId: "usr_12345", 4 CustomClaims: map[string]string{ 5 "team": "engineering", 6 "environment": "production", 7 }, 8 Description: "Deployment service token", 9 }, 10 ) 11 if err != nil { 12 log.Printf("Failed to create user token: %v", err) 13 return 14 } 15 16 opaqueToken := userToken.Token 17 tokenId := userToken.TokenId ``` * Java ```java 1 import java.util.Map; 2 import com.scalekit.grpc.scalekit.v1.tokens.CreateTokenResponse; 3 4 try { 5 Map customClaims = Map.of( 6 "team", "engineering", 7 "environment", "production" 8 ); 9 10 CreateTokenResponse userToken = scalekitClient.tokens().create( 11 organizationId, "usr_12345", customClaims, null, "Deployment service token" 12 ); 13 14 String opaqueToken = userToken.getToken(); 15 String tokenId = userToken.getTokenId(); 16 } catch (Exception e) { 17 System.err.println("Failed to create token: " + e.getMessage()); 18 } ``` The response contains three fields: | Field | Description | | ------------ | ---------------------------------------------------------------------------------------- | | `token` | The API key string. **Returned only at creation.** | | `token_id` | An identifier (format: `apit_xxxxx`) for referencing the token in management operations. | | `token_info` | Metadata including organization, user, custom claims, and timestamps. | 3. ## Validate a token [Section titled “Validate a token”](#validate-a-token) When your API server receives a request with an API key, you’ll want to verify it’s legitimate before processing the request. Pass the key to Scalekit — it validates the key server-side and returns the associated organization, user, and metadata context. * Node.js ```javascript 1 import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node'; 2 3 try { 4 const result = await scalekit.token.validateToken(opaqueToken); 5 6 const orgId = result.tokenInfo?.organizationId; 7 const userId = result.tokenInfo?.userId; 8 const claims = result.tokenInfo?.customClaims; 9 } catch (error) { 10 if (error instanceof ScalekitValidateTokenFailureException) { 11 // Token is invalid, expired, or revoked 12 console.error('Token validation failed:', error.message); 13 } 14 } ``` * Python ```python 1 from scalekit import ScalekitValidateTokenFailureException 2 3 try: 4 result = scalekit_client.tokens.validate_token(token=opaque_token) 5 6 org_id = result.token_info.organization_id 7 user_id = result.token_info.user_id 8 claims = result.token_info.custom_claims 9 except ScalekitValidateTokenFailureException: 10 # Token is invalid, expired, or revoked 11 print("Token validation failed") ``` * Go ```go 1 result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken) 2 if errors.Is(err, scalekit.ErrTokenValidationFailed) { 3 // Token is invalid, expired, or revoked 4 log.Printf("Token validation failed: %v", err) 5 return 6 } 7 8 orgId := result.TokenInfo.OrganizationId 9 userId := result.TokenInfo.GetUserId() // *string — nil for org-scoped tokens 10 claims := result.TokenInfo.CustomClaims ``` * Java ```java 1 import java.util.Map; 2 import com.scalekit.exceptions.TokenInvalidException; 3 import com.scalekit.grpc.scalekit.v1.tokens.ValidateTokenResponse; 4 5 try { 6 ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken); 7 8 String orgId = result.getTokenInfo().getOrganizationId(); 9 String userId = result.getTokenInfo().getUserId(); 10 Map claims = result.getTokenInfo().getCustomClaimsMap(); 11 } catch (TokenInvalidException e) { 12 // Token is invalid, expired, or revoked 13 System.err.println("Token validation failed: " + e.getMessage()); 14 } ``` If the API key is invalid, expired, or has been revoked, validation fails with a specific error that you can catch and handle in your code. This makes it easy to reject unauthorized requests in your API middleware. ### Access roles and organization details [Section titled “Access roles and organization details”](#access-roles-and-organization-details) Beyond the basic organization and user information, the validation response also includes any roles assigned to the user and external identifiers you’ve configured for the organization. These are useful for making authorization decisions without additional database lookups. * Node.js ```javascript 1 try { 2 const result = await scalekit.token.validateToken(opaqueToken); 3 4 // Roles assigned to the user 5 const roles = result.tokenInfo?.roles; 6 7 // External identifiers for mapping to your system 8 const externalOrgId = result.tokenInfo?.organizationExternalId; 9 const externalUserId = result.tokenInfo?.userExternalId; 10 } catch (error) { 11 if (error instanceof ScalekitValidateTokenFailureException) { 12 console.error('Token validation failed:', error.message); 13 } 14 } ``` * Python ```python 1 try: 2 result = scalekit_client.tokens.validate_token(token=opaque_token) 3 4 # Roles assigned to the user 5 roles = result.token_info.roles 6 7 # External identifiers for mapping to your system 8 external_org_id = result.token_info.organization_external_id 9 external_user_id = result.token_info.user_external_id 10 except ScalekitValidateTokenFailureException: 11 print("Token validation failed") ``` * Go ```go 1 result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken) 2 if errors.Is(err, scalekit.ErrTokenValidationFailed) { 3 log.Printf("Token validation failed: %v", err) 4 return 5 } 6 7 // Roles assigned to the user 8 roles := result.TokenInfo.Roles 9 10 // External identifiers for mapping to your system 11 externalOrgId := result.TokenInfo.OrganizationExternalId 12 externalUserId := result.TokenInfo.GetUserExternalId() // *string — nil if no external ID ``` * Java ```java 1 import java.util.List; 2 import com.scalekit.exceptions.TokenInvalidException; 3 import com.scalekit.grpc.scalekit.v1.tokens.ValidateTokenResponse; 4 5 try { 6 ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken); 7 8 // Roles assigned to the user 9 List roles = result.getTokenInfo().getRolesList(); 10 11 // External identifiers for mapping to your system 12 String externalOrgId = result.getTokenInfo().getOrganizationExternalId(); 13 String externalUserId = result.getTokenInfo().getUserExternalId(); 14 } catch (TokenInvalidException e) { 15 System.err.println("Token validation failed: " + e.getMessage()); 16 } ``` ### Access custom metadata [Section titled “Access custom metadata”](#access-custom-metadata) If you attached custom claims when creating the API key, they come back in every validation response. This is a convenient way to make fine-grained authorization decisions — like restricting access by team or environment — without hitting your database. * Node.js ```javascript 1 try { 2 const result = await scalekit.token.validateToken(opaqueToken); 3 4 const team = result.tokenInfo?.customClaims?.team; 5 const environment = result.tokenInfo?.customClaims?.environment; 6 7 // Use metadata for authorization 8 if (environment !== 'production') { 9 return res.status(403).json({ error: 'Production access required' }); 10 } 11 } catch (error) { 12 if (error instanceof ScalekitValidateTokenFailureException) { 13 console.error('Token validation failed:', error.message); 14 } 15 } ``` * Python ```python 1 try: 2 result = scalekit_client.tokens.validate_token(token=opaque_token) 3 4 team = result.token_info.custom_claims.get("team") 5 environment = result.token_info.custom_claims.get("environment") 6 7 # Use metadata for authorization 8 if environment != "production": 9 return jsonify({"error": "Production access required"}), 403 10 except ScalekitValidateTokenFailureException: 11 print("Token validation failed") ``` * Go ```go 1 result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken) 2 if errors.Is(err, scalekit.ErrTokenValidationFailed) { 3 log.Printf("Token validation failed: %v", err) 4 return 5 } 6 7 team := result.TokenInfo.CustomClaims["team"] 8 environment := result.TokenInfo.CustomClaims["environment"] 9 10 // Use metadata for authorization 11 if environment != "production" { 12 c.JSON(403, gin.H{"error": "Production access required"}) 13 return 14 } ``` * Java ```java 1 import java.util.Map; 2 import com.scalekit.exceptions.TokenInvalidException; 3 import com.scalekit.grpc.scalekit.v1.tokens.ValidateTokenResponse; 4 5 try { 6 ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken); 7 8 String team = result.getTokenInfo().getCustomClaimsMap().get("team"); 9 String environment = result.getTokenInfo().getCustomClaimsMap().get("environment"); 10 11 // Use metadata for authorization 12 if (!"production".equals(environment)) { 13 return ResponseEntity.status(403).body(Map.of("error", "Production access required")); 14 } 15 } catch (TokenInvalidException e) { 16 System.err.println("Token validation failed: " + e.getMessage()); 17 } ``` 4. ## List tokens [Section titled “List tokens”](#list-tokens) You can retrieve all active API keys for an organization at any time. The response supports pagination for large result sets, and you can filter by user to find keys scoped to a specific person. * Node.js ```javascript 1 try { 2 // List tokens for an organization 3 const response = await scalekit.token.listTokens(organizationId, { 4 pageSize: 10, 5 }); 6 7 for (const token of response.tokens) { 8 console.log(token.tokenId, token.description); 9 } 10 11 // Paginate through results 12 if (response.nextPageToken) { 13 const nextPage = await scalekit.token.listTokens(organizationId, { 14 pageSize: 10, 15 pageToken: response.nextPageToken, 16 }); 17 } 18 19 // Filter tokens by user 20 const userTokens = await scalekit.token.listTokens(organizationId, { 21 userId: 'usr_12345', 22 }); 23 } catch (error) { 24 console.error('Failed to list tokens:', error.message); 25 } ``` * Python ```python 1 try: 2 # List tokens for an organization 3 response = scalekit_client.tokens.list_tokens( 4 organization_id=organization_id, 5 page_size=10, 6 ) 7 8 for token in response.tokens: 9 print(token.token_id, token.description) 10 11 # Paginate through results 12 if response.next_page_token: 13 next_page = scalekit_client.tokens.list_tokens( 14 organization_id=organization_id, 15 page_size=10, 16 page_token=response.next_page_token, 17 ) 18 19 # Filter tokens by user 20 user_tokens = scalekit_client.tokens.list_tokens( 21 organization_id=organization_id, 22 user_id="usr_12345", 23 ) 24 except Exception as e: 25 print(f"Failed to list tokens: {e}") ``` * Go ```go 1 // List tokens for an organization 2 response, err := scalekitClient.Token().ListTokens( 3 ctx, organizationId, scalekit.ListTokensOptions{ 4 PageSize: 10, 5 }, 6 ) 7 if err != nil { 8 log.Printf("Failed to list tokens: %v", err) 9 return 10 } 11 12 for _, token := range response.Tokens { 13 fmt.Println(token.TokenId, token.GetDescription()) 14 } 15 16 // Paginate through results 17 if response.NextPageToken != "" { 18 nextPage, err := scalekitClient.Token().ListTokens( 19 ctx, organizationId, scalekit.ListTokensOptions{ 20 PageSize: 10, 21 PageToken: response.NextPageToken, 22 }, 23 ) 24 if err != nil { 25 log.Printf("Failed to fetch next page: %v", err) 26 return 27 } 28 _ = nextPage // process nextPage.Tokens 29 } 30 31 // Filter tokens by user 32 userTokens, err := scalekitClient.Token().ListTokens( 33 ctx, organizationId, scalekit.ListTokensOptions{ 34 UserId: "usr_12345", 35 }, 36 ) 37 if err != nil { 38 log.Printf("Failed to list user tokens: %v", err) 39 return 40 } 41 _ = userTokens // process userTokens.Tokens ``` * Java ```java 1 import com.scalekit.grpc.scalekit.v1.tokens.ListTokensResponse; 2 import com.scalekit.grpc.scalekit.v1.tokens.Token; 3 4 try { 5 ListTokensResponse response = scalekitClient.tokens().list(organizationId, 10, null); 6 for (Token token : response.getTokensList()) { 7 System.out.println(token.getTokenId() + " " + token.getDescription()); 8 } 9 } catch (Exception e) { 10 System.err.println("Failed to list tokens: " + e.getMessage()); 11 } 12 13 try { 14 ListTokensResponse response = scalekitClient.tokens().list(organizationId, 10, null); 15 if (!response.getNextPageToken().isEmpty()) { 16 ListTokensResponse nextPage = scalekitClient.tokens().list( 17 organizationId, 10, response.getNextPageToken() 18 ); 19 } 20 } catch (Exception e) { 21 System.err.println("Failed to paginate tokens: " + e.getMessage()); 22 } 23 24 try { 25 ListTokensResponse userTokens = scalekitClient.tokens().list( 26 organizationId, "usr_12345", 10, null 27 ); 28 } catch (Exception e) { 29 System.err.println("Failed to list user tokens: " + e.getMessage()); 30 } ``` The response includes `totalCount` for the total number of matching tokens and `nextPageToken` / `prevPageToken` cursors for navigating pages. 5. ## Invalidate a token [Section titled “Invalidate a token”](#invalidate-a-token) When you need to revoke an API key — for example, when an employee leaves or you suspect credentials have been compromised — you can invalidate it through Scalekit. Revocation takes effect instantly: the very next validation request for that key will fail. This operation is **idempotent**, so calling invalidate on an already-revoked key succeeds without error. * Node.js ```javascript 1 try { 2 // Invalidate by API key string 3 await scalekit.token.invalidateToken(opaqueToken); 4 5 // Or invalidate by token_id (useful when you store tokenId for lifecycle management) 6 await scalekit.token.invalidateToken(tokenId); 7 } catch (error) { 8 console.error('Failed to invalidate token:', error.message); 9 } ``` * Python ```python 1 try: 2 # Invalidate by API key string 3 scalekit_client.tokens.invalidate_token(token=opaque_token) 4 5 # Or invalidate by token_id (useful when you store token_id for lifecycle management) 6 scalekit_client.tokens.invalidate_token(token=token_id) 7 except Exception as e: 8 print(f"Failed to invalidate token: {e}") ``` * Go ```go 1 // Invalidate by API key string 2 if err := scalekitClient.Token().InvalidateToken(ctx, opaqueToken); err != nil { 3 log.Printf("Failed to invalidate token: %v", err) 4 } 5 6 // Or invalidate by token_id (useful when you store tokenId for lifecycle management) 7 if err := scalekitClient.Token().InvalidateToken(ctx, tokenId); err != nil { 8 log.Printf("Failed to invalidate token: %v", err) 9 } ``` * Java ```java 1 try { 2 // Invalidate by API key string 3 scalekitClient.tokens().invalidate(opaqueToken); 4 5 // Or invalidate by token_id (useful when you store tokenId for lifecycle management) 6 scalekitClient.tokens().invalidate(tokenId); 7 } catch (Exception e) { 8 System.err.println("Failed to invalidate token: " + e.getMessage()); 9 } ``` 6. ## Protect your API endpoints [Section titled “Protect your API endpoints”](#protect-your-api-endpoints) Now let’s put it all together. The most common pattern is to add API key validation as middleware in your API server. Extract the Bearer token from the `Authorization` header, validate it through Scalekit, and use the returned context for authorization decisions. * Node.js Express.js ```javascript 1 import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node'; 2 3 async function authenticateToken(req, res, next) { 4 const authHeader = req.headers['authorization']; 5 const token = authHeader && authHeader.split(' ')[1]; 6 7 if (!token) { 8 // Reject requests without credentials to prevent unauthorized access 9 return res.status(401).json({ error: 'Missing authorization token' }); 10 } 11 12 try { 13 // Server-side validation — Scalekit checks token status in real time 14 const result = await scalekit.token.validateToken(token); 15 // Attach token context to the request for downstream handlers 16 req.tokenInfo = result.tokenInfo; 17 next(); 18 } catch (error) { 19 if (error instanceof ScalekitValidateTokenFailureException) { 20 // Revoked, expired, or malformed tokens are rejected immediately 21 return res.status(401).json({ error: 'Invalid or expired token' }); 22 } 23 throw error; 24 } 25 } 26 27 // Apply to protected routes 28 app.get('/api/resources', authenticateToken, (req, res) => { 29 const orgId = req.tokenInfo.organizationId; 30 // Serve resources scoped to this organization 31 }); ``` * Python Flask ```python 1 from functools import wraps 2 from flask import request, jsonify, g 3 from scalekit import ScalekitValidateTokenFailureException 4 5 def authenticate_token(f): 6 @wraps(f) 7 def decorated(*args, **kwargs): 8 auth_header = request.headers.get("Authorization", "") 9 if not auth_header.startswith("Bearer "): 10 # Reject requests without credentials to prevent unauthorized access 11 return jsonify({"error": "Missing authorization token"}), 401 12 13 token = auth_header.split(" ")[1] 14 15 try: 16 # Server-side validation — Scalekit checks token status in real time 17 result = scalekit_client.tokens.validate_token(token=token) 18 # Attach token context for downstream handlers 19 g.token_info = result.token_info 20 except ScalekitValidateTokenFailureException: 21 # Revoked, expired, or malformed tokens are rejected immediately 22 return jsonify({"error": "Invalid or expired token"}), 401 23 24 return f(*args, **kwargs) 25 return decorated 26 27 # Apply to protected routes 28 @app.route("/api/resources") 29 @authenticate_token 30 def get_resources(): 31 org_id = g.token_info.organization_id 32 # Serve resources scoped to this organization ``` * Go Gin ```go 1 func AuthenticateToken(scalekitClient scalekit.Scalekit) gin.HandlerFunc { 2 return func(c *gin.Context) { 3 authHeader := c.GetHeader("Authorization") 4 if !strings.HasPrefix(authHeader, "Bearer ") { 5 // Reject requests without credentials to prevent unauthorized access 6 c.JSON(401, gin.H{"error": "Missing authorization token"}) 7 c.Abort() 8 return 9 } 10 11 token := strings.TrimPrefix(authHeader, "Bearer ") 12 13 // Server-side validation — Scalekit checks token status in real time 14 result, err := scalekitClient.Token().ValidateToken(c.Request.Context(), token) 15 if err != nil { 16 if errors.Is(err, scalekit.ErrTokenValidationFailed) { 17 // Revoked, expired, or malformed tokens are rejected immediately 18 c.JSON(401, gin.H{"error": "Invalid or expired token"}) 19 } else { 20 // Surface transport or unexpected errors as 500 21 c.JSON(500, gin.H{"error": "Internal server error"}) 22 } 23 c.Abort() 24 return 25 } 26 27 // Attach token context for downstream handlers 28 c.Set("tokenInfo", result.TokenInfo) 29 c.Next() 30 } 31 } 32 33 // Apply to protected routes 34 r.GET("/api/resources", AuthenticateToken(scalekitClient), func(c *gin.Context) { 35 tokenInfo := c.MustGet("tokenInfo").(*scalekit.TokenInfo) 36 orgId := tokenInfo.OrganizationId 37 // Serve resources scoped to this organization 38 }) ``` * Java Spring Boot ```java 1 import com.scalekit.exceptions.TokenInvalidException; 2 import com.scalekit.grpc.scalekit.v1.tokens.Token; 3 import com.scalekit.grpc.scalekit.v1.tokens.ValidateTokenResponse; 4 5 @Component 6 public class TokenAuthFilter extends OncePerRequestFilter { 7 private final ScalekitClient scalekitClient; 8 9 public TokenAuthFilter(ScalekitClient scalekitClient) { 10 this.scalekitClient = scalekitClient; 11 } 12 13 @Override 14 protected void doFilterInternal( 15 HttpServletRequest request, 16 HttpServletResponse response, 17 FilterChain filterChain 18 ) throws ServletException, IOException { 19 String authHeader = request.getHeader("Authorization"); 20 if (authHeader == null || !authHeader.startsWith("Bearer ")) { 21 // Reject requests without credentials to prevent unauthorized access 22 response.sendError(401, "Missing authorization token"); 23 return; 24 } 25 26 String token = authHeader.substring(7); 27 28 try { 29 // Server-side validation — Scalekit checks token status in real time 30 ValidateTokenResponse result = scalekitClient.tokens().validate(token); 31 // Attach token context for downstream handlers 32 request.setAttribute("tokenInfo", result.getTokenInfo()); 33 filterChain.doFilter(request, response); 34 } catch (TokenInvalidException e) { 35 // Revoked, expired, or malformed tokens are rejected immediately 36 response.sendError(401, "Invalid or expired token"); 37 } 38 } 39 } 40 41 // Access in your controller 42 @GetMapping("/api/resources") 43 public ResponseEntity getResources(HttpServletRequest request) { 44 Token tokenInfo = (Token) request.getAttribute("tokenInfo"); 45 String orgId = tokenInfo.getOrganizationId(); 46 // Serve resources scoped to this organization 47 } ``` ### Using validation context for data filtering [Section titled “Using validation context for data filtering”](#using-validation-context-for-data-filtering) After validation succeeds, your middleware has access to the organization and (optionally) user context. Use this context to filter the data your endpoint returns — no additional database queries needed. **For organization-scoped keys**: Extract the organization ID from the validation response. Your endpoint then returns resources belonging to that organization. If a customer authenticates with an organization-scoped key, they get access to all their workspace data. **For user-scoped keys**: Extract both organization ID and user ID. Filter your query to return only resources belonging to that user within the organization. If a team member authenticates with a user-scoped key, they see only their assigned tasks, their owned projects, or their allocated resources — depending on your application logic. The validation response is your source of truth. Trust the organization and user context it provides, and use it to build your authorization queries without additional lookups. Here are a few tips to help you get the most out of API keys in production: * **Store API keys securely**: Treat API keys like passwords. Store them in encrypted secrets managers or environment variables. Never log keys, commit them to version control, or expose them in client-side code. * **Set expiry for time-limited access**: Use the `expiry` parameter for keys that should automatically become invalid after a set period. This limits the blast radius if a key is compromised. * **Use custom claims for context**: Attach metadata like `team`, `environment`, or `service` as custom claims. Your API middleware can use these claims for fine-grained authorization without additional database lookups. * **Rotate keys safely**: To rotate an API key, create a new key, update the consuming service to use the new key, verify the new key works, then invalidate the old key. This avoids downtime during rotation. You now have everything you need to issue, validate, and manage API keys in your application. --- # DOCUMENT BOUNDARY --- # Add users to organizations > Ways in which users join or get added to organizations The journey of a user into your application begins with how they join an organization. A smooth onboarding experience sets the tone for their entire interaction with your product, while administrators need flexible options to manage their organization members. Scalekit supports a variety of ways for users to join organizations. This guide covers methods ranging from manual additions in the dashboard to fully automated provisioning. ## Enable user invitations through your app [Section titled “Enable user invitations through your app”](#enable-user-invitations-through-your-app) Scalekit lets you add user invitation features to your app, allowing users to invite others to join their organization. 1. #### Begin the invite flow [Section titled “Begin the invite flow”](#begin-the-invite-flow) When a user clicks the invite button in your application, retrieve the `organization_id` from their ID token or the application’s context. Then, call the Scalekit SDK with the invitee’s email address to send the invitation. * Node.js Express.js invitation API ```javascript 1 // POST /api/organizations/:orgId/invite 2 app.post('/api/organizations/:orgId/invite', async (req, res) => { 3 const { orgId } = req.params 4 const { email } = req.body 5 6 try { 7 // Create user and add to organization with invitation 8 const { user } = await scalekit.user.createUserAndMembership(orgId, { 9 email, 10 sendInvitationEmail: true, // Scalekit sends the invitation email 11 }) 12 13 res.json({ 14 message: 'Invitation sent successfully', 15 userId: user.id, 16 email: user.email 17 }) 18 } catch (error) { 19 res.status(400).json({ error: error.message }) 20 } 21 }) ``` * Python Django invitation API ```python 1 # Python - Django invitation API 2 @api_view(['POST']) 3 def invite_user_to_organization(request, org_id): 4 email = request.data.get('email') 5 6 try: 7 # Create user and add to organization with invitation 8 user_response = scalekit_client.user.create_user_and_membership(org_id, { 9 'email': email, 10 'send_invitation_email': True, # Scalekit sends the invitation email 11 }) 12 13 return JsonResponse({ 14 'message': 'Invitation sent successfully', 15 'user_id': user_response['user']['id'], 16 'email': user_response['user']['email'] 17 }) 18 except Exception as error: 19 return JsonResponse({'error': str(error)}, status=400) ``` * Go Gin invitation API ```go 1 // Go - Gin invitation API 2 func inviteUserToOrganization(c *gin.Context) { 3 orgID := c.Param("orgId") 4 5 var req struct { 6 Email string `json:"email"` 7 } 8 9 if err := c.ShouldBindJSON(&req); err != nil { 10 c.JSON(400, gin.H{"error": err.Error()}) 11 return 12 } 13 14 // Create user and add to organization with invitation 15 userResp, err := scalekitClient.User.CreateUserAndMembership(ctx, orgID, scalekit.CreateUserAndMembershipRequest{ 16 Email: req.Email, 17 SendInvitationEmail: scalekit.Bool(true), // Scalekit sends the invitation email 18 }) 19 20 if err != nil { 21 c.JSON(400, gin.H{"error": err.Error()}) 22 return 23 } 24 25 c.JSON(200, gin.H{ 26 "message": "Invitation sent successfully", 27 "user_id": userResp.User.Id, 28 "email": userResp.User.Email, 29 }) 30 } ``` * Java Spring Boot invitation API ```java 1 // Java - Spring Boot invitation API 2 @PostMapping("/api/organizations/{orgId}/invite") 3 public ResponseEntity> inviteUserToOrganization( 4 @PathVariable String orgId, 5 @RequestBody InviteRequest request, 6 HttpSession session 7 ) { 8 try { 9 // Create user and add to organization with invitation 10 CreateUser createUser = CreateUser.newBuilder() 11 .setEmail(request.email()) 12 .setSendInvitationEmail(true) // Scalekit sends the invitation email 13 .build(); 14 15 CreateUserAndMembershipResponse response = scalekitClient.users() 16 .createUserAndMembership(orgId, createUser); 17 18 return ResponseEntity.ok(Map.of( 19 "message", "Invitation sent successfully", 20 "user_id", response.getUser().getId(), 21 "email", response.getUser().getEmail() 22 )); 23 } catch (Exception error) { 24 return ResponseEntity.badRequest().body( 25 Map.of("error", error.getMessage()) 26 ); 27 } 28 } ``` This sends a email invitation to invitee to join the organization. 2. #### Set up initiate login endpoint [Section titled “Set up initiate login endpoint”](#set-up-initiate-login-endpoint) After the invitee clicks the invitation link they receive via email, Scalekit will handle verifying their identity in the background through the unique link embedded. Once verified, Scalekit automatically tries to log the invitee into your application by redirecting them to your app’s [configured initiate login endpoint](/guides/dashboard/intitate-login-endpoint/). Let’s go ahead and implement this endpoint. * Node.js routes/auth.js ```javascript 1 // Handle indirect auth entry points 2 app.get('/login', (req, res) => { 3 const redirectUri = 'http://localhost:3000/auth/callback'; 4 const options = { 5 scopes: ['openid', 'profile', 'email', 'offline_access'] 6 }; 7 8 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); 9 res.redirect(authorizationUrl); 10 }); ``` * Python routes/auth.py ```python 1 from flask import redirect 2 from scalekit import AuthorizationUrlOptions 3 4 # Handle indirect auth entry points 5 @app.route('/login') 6 def login(): 7 redirect_uri = 'http://localhost:3000/auth/callback' 8 options = AuthorizationUrlOptions() 9 options.scopes = ['openid', 'profile', 'email', 'offline_access'] 10 options.state = session['oauth_state'] 11 12 authorization_url = scalekit_client.get_authorization_url(redirect_uri, options) 13 return redirect(authorization_url) ``` * Go routes/auth.go ```go 1 // Handle indirect auth entry points 2 r.GET("/login", func(c *gin.Context) { 3 redirectUri := "http://localhost:3000/auth/callback" 4 options := scalekitClient.AuthorizationUrlOptions{ 5 Scopes: []string{"openid", "profile", "email", "offline_access"} 6 } 7 8 authorizationUrl, _ := scalekitClient.GetAuthorizationUrl(redirectUri, options) 9 c.Redirect(http.StatusFound, authorizationUrl.String()) 10 }) ``` * Java AuthController.java ```java 1 import org.springframework.web.bind.annotation.GetMapping; 2 import org.springframework.web.bind.annotation.RestController; 3 import java.net.URL; 4 5 // Handle indirect auth entry points 6 @GetMapping("/login") 7 public String login() { 8 String redirectUri = "http://localhost:3000/auth/callback"; 9 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 10 options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access")); 11 12 URL authorizationUrl = scalekitClient.authentication().getAuthorizationUrl(redirectUri, options); 13 return "redirect:" + authorizationUrl.toString(); 14 } ``` This redirection ensures that the invitee is logged into your application after they accept the invitation. User won’t see a login page along the way since the identity is already verified through the unique link embedded in the invitation email. The user will get an invitation email from Scalekit to accept the invitation. ## Enable Just-In-Time (JIT) provisioning [Section titled “Enable Just-In-Time (JIT) provisioning”](#enable-just-in-time-jit-provisioning) Organization administrators, especially at enterprises, prefer to have users verify their identity through their preferred identity provider (such as Okta, Microsoft Entra ID, etc.). This is particularly useful for enterprises with many users who need to ensure that only organization members can access the application. Scalekit will provision the user accounts in your app automatically when they sign in through SSO for the first time and map the user to the same organization. [Learn more](/authenticate/manage-users-orgs/jit-provisioning/) ## Enable SCIM provisioning [Section titled “Enable SCIM provisioning”](#enable-scim-provisioning) Enterprises often rely on user directory providers (such as Okta, Microsoft Entra ID, etc.) to handle user management. This enables their organization administrators to control and manage access for organization members efficiently. Scalekit supports SCIM provisioning, allowing your app to connect with these user directory providers so that user accounts are automatically created or removed in your app when users join or leave the organization. This automation is especially valuable for enterprise customers who want to ensure their licenses or seats are allocated efficiently, with organization admins managing access based on user groups. [Learn more](/authenticate/manage-users-orgs/scim-provisioning/) ## Add users through dashboard [Section titled “Add users through dashboard”](#add-users-through-dashboard) For administrative or support purposes, the Scalekit dashboard allows you to add new members directly to a customer’s organization 1. In the Scalekit dashboard, navigate to **Dashboard > Organizations**. 2. Select the organization you want to add a user to. 3. Go to the **Users** tab and click Invite User. 4. Fill out the invitation form: * Email Address: The user’s email * Role: Assign a role from the dropdown (e.g., Admin, Member, or a custom organization role) * Personal Information (Optional): Add the user’s first name, last name, and display name 5. Click **Send Invitation** The user will receive an email with a link to accept the invitation and join your organization. Once they accept, their status will update in the Users tab. ## Common questions [Section titled “Common questions”](#common-questions) --- # DOCUMENT BOUNDARY --- # Organization session policy > Override application-level session timeouts for specific organizations with custom absolute and idle session policies By default, all organizations inherit the session policy configured at the application level — covering absolute session duration and idle timeout. When an enterprise customer requires stricter or different session controls than your application defaults, you can set a custom session policy on a per-organization basis. Scalekit always enforces the **stricter of the two** (application vs. organization) at session creation time, so organization policies can only tighten — not relax — your application-level defaults. ## How it works [Section titled “How it works”](#how-it-works) Each organization can either inherit the application session policy or define its own. The two settings you can customize per organization are: | Setting | Behavior | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Absolute session timeout** | Maximum session lifetime regardless of activity. Scalekit applies `min(app value, org value)`. | | **Idle session timeout** | Inactivity period after which the session expires. Enabled if either the app or org has it on; duration is `min(app value, org value)`. | **Access token lifetime** is not configurable at the org level. It remains an application-level setting only. ## Set up custom session policy for an organization [Section titled “Set up custom session policy for an organization”](#set-up-custom-session-policy-for-an-organization) ### Prerequisites [Section titled “Prerequisites”](#prerequisites) Enable the **Session Policy** feature for an organization before configuring a custom policy. Navigate to **Dashboard > Organizations > \[Organization] > Overview > Edit** and turn on **Session Policy** feature. You can also use the [organization settings API](/apis/#tag/organizations/PATCH/api/v1/organizations/%7Bid%7D/settings). ![Enable session policy feature for organization.](/.netlify/images?url=_astro%2F2026-05-21-16-43-01.CaYNvMBM.png\&w=2920\&h=1570\&dpl=6aaa70ad2ea7b40008ad2afd) ### Configure via dashboard [Section titled “Configure via dashboard”](#configure-via-dashboard) Once the **Session Policy** feature is enabled for the organization, you can configure a custom policy for the organization via the Scalekit dashboard. 1. Go to **Dashboard > Organizations** and open the organization. 2. Click the **Session Policy** tab. 3. Select **Custom** to apply org-specific settings, or **Application** to revert to defaults. 4. Set the **Absolute session timeout** and **Idle session timeout** for the organization. 5. Click **Save**. ![Edit session policy for the organization.](/.netlify/images?url=_astro%2Forganization-session-policy.CyEzWmK_.png\&w=2930\&h=1584\&dpl=6aaa70ad2ea7b40008ad2afd) ### Let org admins self-serve via Hosted Widgets [Section titled “Let org admins self-serve via Hosted Widgets”](#let-org-admins-self-serve-via-hosted-widgets) You can let your customers manage their own session policy through [Hosted Widgets](/authenticate/manage-users-orgs/hosted-widgets/) — an embeddable self-service portal that lets your customers manage organization and user-level settings. When the `Session Policy` feature is enabled for an organization, the Session Policy widget becomes available in the Hosted Widget portal. ### Configure via API/SDK [Section titled “Configure via API/SDK”](#configure-via-apisdk) 1. **Get the current session policy** Retrieve the active session policy for an organization to display it in your settings UI or audit the current configuration. * Node.js Get session policy ```javascript 1 try { 2 const policy = await scalekit.organization.getOrganizationSessionPolicy('org_12345'); 3 4 // policySource: 1 = APPLICATION (inheriting defaults), 2 = CUSTOM (org-specific values active) 5 console.log('Policy source:', policy.policySource); 6 console.log('Absolute timeout (minutes):', policy.absoluteSessionTimeout); 7 console.log('Idle timeout enabled:', policy.idleSessionTimeoutEnabled); 8 } catch (error) { 9 console.error('Failed to get session policy:', error.message); 10 } ``` * Python Get session policy ```python 1 from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType 2 3 try: 4 response, _ = scalekit_client.organization.get_organization_session_policy('org_12345') 5 policy = response.policy 6 7 if policy.policy_source == SessionPolicyType.CUSTOM: 8 print('Absolute timeout (minutes):', policy.absolute_session_timeout.value) 9 print('Idle timeout enabled:', policy.idle_session_timeout_enabled.value) 10 except Exception as e: 11 print('Failed to get session policy:', e) ``` * Go Get session policy ```go 1 policy, err := scalekitClient.Organization().GetOrganizationSessionPolicy(ctx, "org_12345") 2 if err != nil { 3 log.Fatal(err) 4 } 5 6 if policy.PolicySource == scalekit.SessionPolicySourceCustom { 7 fmt.Println("Absolute timeout (minutes):", policy.AbsoluteSessionTimeout.GetValue()) 8 fmt.Println("Idle timeout enabled:", policy.IdleSessionTimeoutEnabled.GetValue()) 9 } ``` * Java Get session policy ```java 1 import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; 2 import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; 3 4 try { 5 OrganizationSessionPolicySettings policy = 6 scalekitClient.organizations().getOrganizationSessionPolicy("org_12345"); 7 8 if (policy.getPolicySource() == SessionPolicyType.CUSTOM) { 9 System.out.println("Absolute timeout (minutes): " + policy.getAbsoluteSessionTimeout().getValue()); 10 System.out.println("Idle timeout enabled: " + policy.getIdleSessionTimeoutEnabled().getValue()); 11 } 12 } catch (Exception e) { 13 System.err.println("Failed to get session policy: " + e.getMessage()); 14 } ``` 2. **Set a custom session policy** Apply a custom policy when an organization requires different session durations than your application defaults. * Node.js Set custom session policy ```javascript 1 try { 2 const updated = await scalekit.organization.updateOrganizationSessionPolicy('org_12345', { 3 policySource: 'CUSTOM', 4 absoluteSessionTimeout: 480, 5 absoluteSessionTimeoutUnit: 'MINUTES', 6 idleSessionTimeoutEnabled: true, 7 idleSessionTimeout: 60, 8 idleSessionTimeoutUnit: 'MINUTES', 9 }); 10 11 console.log('Policy updated:', updated.policySource); 12 } catch (error) { 13 console.error('Failed to update session policy:', error.message); 14 } ``` * Python Set custom session policy ```python 1 from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType 2 from scalekit.v1.commons.commons_pb2 import TimeUnit 3 4 try: 5 response, _ = scalekit_client.organization.update_organization_session_policy( 6 organization_id='org_12345', 7 policy_source=SessionPolicyType.CUSTOM, 8 absolute_session_timeout=480, 9 absolute_session_timeout_unit=TimeUnit.MINUTES, 10 idle_session_timeout_enabled=True, 11 idle_session_timeout=60, 12 idle_session_timeout_unit=TimeUnit.MINUTES, 13 ) 14 15 print('Policy updated:', response.policy.policy_source) 16 except Exception as e: 17 print('Failed to update session policy:', e) ``` * Go Set custom session policy ```go 1 timeout := int32(480) 2 idleTimeout := int32(60) 3 idleEnabled := true 4 5 updated, err := scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, "org_12345", scalekit.OrganizationSessionPolicy{ 6 PolicySource: scalekit.SessionPolicySourceCustom, 7 AbsoluteSessionTimeout: &timeout, 8 AbsoluteSessionTimeoutUnit: scalekit.TimeUnitMinutes, 9 IdleSessionTimeoutEnabled: &idleEnabled, 10 IdleSessionTimeout: &idleTimeout, 11 IdleSessionTimeoutUnit: scalekit.TimeUnitMinutes, 12 }) 13 if err != nil { 14 log.Fatal(err) 15 } 16 17 fmt.Println("Policy updated:", updated.PolicySource) ``` * Java Set custom session policy ```java 1 import com.google.protobuf.Int32Value; 2 import com.google.protobuf.BoolValue; 3 import com.scalekit.grpc.scalekit.v1.commons.TimeUnit; 4 import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; 5 import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; 6 7 try { 8 OrganizationSessionPolicySettings policy = OrganizationSessionPolicySettings.newBuilder() 9 .setPolicySource(SessionPolicyType.CUSTOM) 10 .setAbsoluteSessionTimeout(Int32Value.of(480)) 11 .setAbsoluteSessionTimeoutUnit(TimeUnit.MINUTES) 12 .setIdleSessionTimeoutEnabled(BoolValue.of(true)) 13 .setIdleSessionTimeout(Int32Value.of(60)) 14 .setIdleSessionTimeoutUnit(TimeUnit.MINUTES) 15 .build(); 16 17 OrganizationSessionPolicySettings updated = 18 scalekitClient.organizations().updateOrganizationSessionPolicy("org_12345", policy); 19 20 System.out.println("Policy updated: " + updated.getPolicySource()); 21 } catch (Exception e) { 22 System.err.println("Failed to update session policy: " + e.getMessage()); 23 } ``` 3. **Revert to application defaults** Remove the custom policy and restore the organization to the application-level session settings. * Node.js Revert to application defaults ```javascript 1 try { 2 await scalekit.organization.updateOrganizationSessionPolicy('org_12345', { 3 policySource: 'APPLICATION', 4 }); 5 } catch (error) { 6 console.error('Failed to revert session policy:', error.message); 7 } ``` * Python Revert to application defaults ```python 1 from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType 2 3 try: 4 scalekit_client.organization.update_organization_session_policy( 5 organization_id='org_12345', 6 policy_source=SessionPolicyType.APPLICATION, 7 ) 8 except Exception as e: 9 print('Failed to revert session policy:', e) ``` * Go Revert to application defaults ```go 1 _, err := scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, "org_12345", scalekit.OrganizationSessionPolicy{ 2 PolicySource: scalekit.SessionPolicySourceApplication, 3 }) 4 if err != nil { 5 log.Fatal(err) 6 } ``` * Java Revert to application defaults ```java 1 import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; 2 import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; 3 4 try { 5 OrganizationSessionPolicySettings policy = OrganizationSessionPolicySettings.newBuilder() 6 .setPolicySource(SessionPolicyType.APPLICATION) 7 .build(); 8 9 scalekitClient.organizations().updateOrganizationSessionPolicy("org_12345", policy); 10 } catch (Exception e) { 11 System.err.println("Failed to revert session policy: " + e.getMessage()); 12 } ``` --- # DOCUMENT BOUNDARY --- # Remove users from organizations > Remove users from organizations through dashboard management and API while maintaining security and compliance As your application grows and teams evolve, your administrators will need to manage user access when employees leave, change roles, or when administrators need to revoke access for security reasons. Proper user removal ensures that access control remains accurate, licenses are managed efficiently, and security is maintained across your organization. When a user is removed from an organization, they immediately lose access to that organization’s resources. The user’s account remains in Scalekit, but their membership status changes, and they can no longer access organization-specific data or features. * User loses access to ONE specific organization * User account remains in Scalekit * User can still access OTHER organizations they belong to * Reversible - user can be re-added later - Node.js Remove users from organizations ```javascript 1 // Use case: Remove user during offboarding workflow triggered by HR system 2 await scalekit.user.deleteMembership({ 3 organizationId: 'org_12345', 4 userId: 'usr_67890' 5 }) ``` - Python Remove users from organizations ```python 1 # Use case: Remove user during offboarding workflow triggered by HR system 2 scalekit_client.users.delete_membership( 3 organization_id="org_12345", 4 user_id="usr_67890" 5 ) ``` - Go Remove users from organizations ```go 1 // Use case: Remove user during offboarding workflow triggered by HR system 2 err := scalekitClient.User().DeleteMembership(ctx, "org_123", "user_456", false) 3 if err != nil { 4 log.Printf("Failed to remove user: %v", err) 5 return err 6 } ``` - Java Remove users from organizations ```java 1 // Use case: Remove user during offboarding workflow triggered by HR system 2 try { 3 scalekitClient.user().deleteMembership("org_123", "user_456"); 4 } catch (Exception e) { 5 log.error("Failed to remove user: " + e.getMessage()); 6 throw e; 7 } ``` The membership is removed, effectively dropping the user’s access to the specified organization. ```diff 1 { 2 "user": { 3 "id": "usr_96194455173857548", 4 "environment_id": "env_58345499215790610", 5 "create_time": "2025-10-25T14:46:03.300Z", 6 "update_time": "2025-10-31T11:33:31.639425Z", 7 "email": "saifshine7+locksmith@gmail.com", 8 "external_id": "hitman", 9 "memberships": [ 10 { 11 "organization_id": "org_96194455157080332", 12 "membership_status": "ACTIVE", 13 "roles": [ 14 { 15 "id": "role_69229687729029148", 16 "name": "admin", 17 "display_name": "Admin" 18 } 19 ], 20 "name": "", 21 "metadata": {}, 22 "display_name": "" 23 }, 24 - { 25 "organization_id": "org_67609586521080405", 26 "membership_status": "PENDING_INVITE", 27 "roles": [ 28 - { 29 "id": "role_69229700009951260", 30 "name": "member", 31 "display_name": "Member" 32 - } 33 - ], 34 "name": "Megasoft Inc", 35 "metadata": {}, 36 "display_name": "Megasoft Inc", 37 "created_at": "2025-10-31T12:38:42.270Z", 38 "expires_at": "2025-11-15T12:38:42.231316Z" 39 - } 40 ], 41 "user_profile": { 42 "id": "usp_96194455173923084", 43 "first_name": "Saif", 44 "last_name": "Shines", 45 "name": "", 46 "locale": "", 47 "email_verified": true, 48 "phone_number": "80384873", 49 "metadata": {}, 50 "custom_attributes": {} 51 }, 52 "metadata": {} 53 } 54 } ``` User removal from an organization involves several important considerations and behaviors. * When a user is removed from an organization and has no other organizational memberships, Scalekit will automatically delete their user account. * Your application is responsible for handling the transfer or deletion of the user’s resources when they are removed from an organization. * Scalekit immediately terminates the user’s active session upon removal from an organization. * Removing a user from one organization does not impact their memberships in other organizations. * When a user is removed from an organization, that organization will be automatically removed from the user’s organization switcher options. ## Automate user removal with directory sync [Section titled “Automate user removal with directory sync”](#automate-user-removal-with-directory-sync) When organizations use enterprise directory providers with [SCIM provisioning](/guides/user-management/scim-provisioning/), users are automatically removed from Scalekit organizations when they’re deprovisioned in the source directory. This ensures consistent access control across all systems without requiring manual intervention. When a user is removed from your enterprise directory provider (such as Okta, Azure AD, or JumpCloud): 1. The directory provider sends a SCIM DELETE request to Scalekit 2. Scalekit automatically removes the user’s membership from the organization by marking the `memberships.membership_status` as `INACTIVE` 3. The user immediately loses access to organization resources 4. Your application receives webhook notifications about the membership change This automation is particularly valuable for enterprise customers who manage large numbers of users and need to ensure that license allocation and access control remain synchronized with their directory provider. ## Remove users in the Scalekit dashboard [Section titled “Remove users in the Scalekit dashboard”](#remove-users-in-the-scalekit-dashboard) Use the Scalekit dashboard when administrators need to manually remove users for compliance, security, support or administrative purposes. This approach provides direct control and visibility into the removal process, making it ideal for situations requiring manual oversight. 1. Sign in to the Scalekit dashboard and navigate to **Dashboard** > **Organizations**. Select the organization from which you want to remove users. 2. Click on the **Users** tab to view all organization members. Locate the user you want to remove from the user list. You can use the search functionality to quickly find specific users by name or email. 3. Click the **Actions** menu (three dots) next to the user’s name and select **Remove from organization**. A confirmation dialog will appear to prevent accidental removals. 4. Review the confirmation dialog to ensure you’re removing the correct user. Click **Remove user** to confirm. The user will immediately lose access to the organization and its resources. --- # DOCUMENT BOUNDARY --- # Create organizations > Ways the organizations are created in Scalekit An Organization enables shared data access and enforces consistent authentication methods, session policies, and access control policies for all its members. Scalekit supports two main approaches to organization creation: 1. **Sign up creates organizations automatically**: When users successfully authenticate with your app, Scalekit automatically creates an organization for them. 2. **User creates organizations themselves**: When your application provides users with the option to create new organizations themselves. For instance, Jira enables users to create their own workspaces. ## Sign up creates organizations automatically [Section titled “Sign up creates organizations automatically”](#sign-up-creates-organizations-automatically) Existing [Scalekit integration](/authenticate/fsa/quickstart/) to authenticate users and handle the login flow automatically generates an organization for each user. The organization ID associated with the user will be included in both the ID token and access token. * Decoded ID token ID token decoded ```json 1 { 2 "at_hash": "ec_jU2ZKpFelCKLTRWiRsg", // Access token hash for validation 3 "aud": [ 4 "skc_58327482062864390" // Audience (your client ID) 5 ], 6 "azp": "skc_58327482062864390", // Authorized party (your client ID) 7 "c_hash": "6wMreK9kWQQY6O5R0CiiYg", // Authorization code hash 8 "client_id": "skc_58327482062864390", // Your application's client ID 9 "email": "john.doe@example.com", // User's email address 10 "email_verified": true, // Whether the user's email is verified 11 "exp": 1742975822, // Expiration time (Unix timestamp) 12 "family_name": "Doe", // User's last name 13 "given_name": "John", // User's first name 14 "iat": 1742974022, // Issued at time (Unix timestamp) 15 "iss": "https://scalekit-z44iroqaaada-dev.scalekit.cloud", // Issuer (Scalekit environment URL) 16 "name": "John Doe", // User's full name 17 "oid": "org_59615193906282635", // Organization ID 18 "sid": "ses_65274187031249433", // Session ID 19 "sub": "usr_63261014140912135" // Subject (user's unique ID) 20 } ``` * Decoded access token Decoded access token ```json 1 { 2 "aud": [ 3 "prd_skc_7848964512134X699" // Audience (API or resource server) 4 ], 5 "client_id": "prd_skc_7848964512134X699", // Your application's client ID 6 "oid": "org_89678001X21929734", // Organization ID 7 "exp": 1758265247, // Expiration time (Unix timestamp) 8 "iat": 1758264947, // Issued at time (Unix timestamp) 9 "iss": "https://login.devramp.ai", // Issuer (Scalekit environment URL) 10 "jti": "tkn_90928731115292X63", // JWT ID (unique token identifier) 11 "nbf": 1758264947, // Not before time (Unix timestamp) 12 "permissions": [ // Scopes or permissions granted 13 "workspace_data:write", 14 "workspace_data:read" 15 ], 16 "roles": [ // User roles within the organization 17 "admin" 18 ], 19 "sid": "ses_90928729571723X24", // Session ID 20 "sub": "usr_8967800122X995270", // Subject (user's unique ID) 21 } ``` ## Allow users to create organizations API [Section titled “Allow users to create organizations ”](#allow-users-to-create-organizations--) Applications often provide options for users to create their own organizations. For example, show an option for users such “Create new workspace” within their app. Use the Scalekit SDK to power such options: * Node.js Create and manage organizations ```javascript 1 const { organization } = await scalekit.organization.createOrganization( 2 'Orion Analytics' 3 ); 4 5 // Use case: Sync organization profile to downstream systems 6 const { organization: fetched } = await scalekit.organization.getOrganization(organization.id); ``` * Python Create and manage organizations ```python 1 from scalekit.v1.organizations.organizations_pb2 import CreateOrganization 2 3 response = scalekit_client.organization.create_organization( 4 CreateOrganization( 5 display_name="Orion Analytics", 6 ) 7 ) 8 9 # Use case: Sync organization profile to downstream systems 10 fetched = scalekit_client.organization.get_organization(response[0].organization.id) ``` * Go Create and manage organizations ```go 1 created, err := scalekitClient.Organization().CreateOrganization( 2 ctx, 3 "Orion Analytics", 4 scalekit.CreateOrganizationOptions{}, 5 ) 6 if err != nil { 7 log.Fatalf("create organization: %v", err) 8 } 9 10 // Use case: Sync organization profile to downstream systems 11 fetched, err := scalekitClient.Organization().GetOrganization(ctx, created.Organization.Id) 12 if err != nil { 13 log.Fatalf("get organization: %v", err) 14 } ``` * Java Create and manage organizations ```java 1 // Use case: Provision a workspace after a sales-assisted onboarding 2 CreateOrganization createOrganization = CreateOrganization.newBuilder() 3 .setDisplayName("Orion Analytics") 4 .build(); 5 6 Organization organization = scalekitClient.organizations().create(createOrganization); 7 8 // Use case: Sync organization profile to downstream systems 9 Organization fetched = scalekitClient.organizations().getById(organization.getId()); ``` ### Set organization properties at creation [Section titled “Set organization properties at creation”](#set-organization-properties-at-creation) Pass additional properties when you create an organization to give it a slug, map it to your own system, or brand its hosted pages. Every property except the display name is optional. | Property | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `display_name` | Human-readable name shown in the dashboard and hosted UI. Required. | | `slug` | DNS-safe identifier such as `orion` or `auth.orion-analytics.com`. Expands `{{org_slug}}` in [template redirect URLs](/guides/dashboard/org-redirect-urls/). | | `external_id` | Your own identifier for the organization, so you can look it up by your system’s ID. | | `logo_url` | Publicly accessible logo URL shown on [branded login pages and portals](/fsa/guides/organization-branding/). | * Node.js Create an organization with properties ```javascript 1 const { organization } = await scalekit.organization.createOrganization( 2 'Orion Analytics', 3 { 4 slug: 'orion', 5 externalId: 'customer_12345', 6 logoUrl: 'https://cdn.orion-analytics.com/logo.png', 7 } 8 ); ``` * Python Create an organization with properties ```python 1 from scalekit.v1.organizations.organizations_pb2 import CreateOrganization 2 3 response = scalekit_client.organization.create_organization( 4 CreateOrganization( 5 display_name="Orion Analytics", 6 slug="orion", 7 external_id="customer_12345", 8 logo_url="https://cdn.orion-analytics.com/logo.png", 9 ) 10 ) ``` * Go Create an organization with properties ```go 1 slug := "orion" 2 externalID := "customer_12345" 3 logoURL := "https://cdn.orion-analytics.com/logo.png" 4 5 created, err := scalekitClient.Organization().CreateOrganization( 6 ctx, 7 "Orion Analytics", 8 scalekit.CreateOrganizationOptions{ 9 Slug: &slug, 10 ExternalId: &externalID, 11 LogoUrl: &logoURL, 12 }, 13 ) 14 if err != nil { 15 log.Fatalf("create organization: %v", err) 16 } ``` * Java Create an organization with properties ```java 1 CreateOrganization createOrganization = CreateOrganization.newBuilder() 2 .setDisplayName("Orion Analytics") 3 .setSlug("orion") 4 .setExternalId("customer_12345") 5 .setLogoUrl("https://cdn.orion-analytics.com/logo.png") 6 .build(); 7 8 Organization organization = scalekitClient.organizations().create(createOrganization); ``` Next, let’s look at how users can be added to organizations. --- # DOCUMENT BOUNDARY --- # Customize user profiles > Tailor user profiles to your business needs by creating and managing user profile attributes in Scalekit User profiles in Scalekit provide essential identity information through standard attributes like email, name, and phone number. However, when your application requires business-specific data such as employee IDs, department codes, or access levels, you need more flexibility. T This guide shows how to extend user profiles with custom attributes that can be created through the dashboard, managed programmatically via API, and synchronized with enterprise identity providers. #### Standard user profile attributes [Section titled “Standard user profile attributes”](#standard-user-profile-attributes) Let’s start by looking at the existing standard attributes in a `user_profile` from the Scalekit’s [Get User API](https://docs.scalekit.com/apis/#tag/users/GET/api/v1/users/%7Bid%7D) response. ```json 1 { 2 "id": "usp_96194455173923084", // Unique user identifier 3 "first_name": "John", // User's given name 4 "last_name": "Doe", // User's family name 5 "name": "John Doe", // Full name for UI display 6 "locale": "en-US", // User's language and region preference 7 "email_verified": true, // Whether the email address has been confirmed 8 "phone_number": "+14155552671", // Contact phone number 9 "metadata": { }, // Additional, non-structured user data 10 "custom_attributes": {} // Business-specific user data 11 } ``` These attributes are also listed in your Scalekit dashboard. Navigate to **Dashboard** > **User Attributes** to see them. Let’s see how we can create a custom attribute. ## Create custom attributes [Section titled “Create custom attributes”](#create-custom-attributes) To add a custom attribute 1. Navigate to **Dashboard** > **User Attributes** and click **Add Attribute**. 2. Configure the new attribute fields: * **Display name** - Human-readable label shown in the dashboard (e.g., “Employee Number”) * **Attribute key** - Internal field name for API and SDK access (e.g., `employee_id`) 3. The new attribute can be used to attach the new information about the user to their user profile. ```diff 1 { 2 "id": "usp_96194455173923084", // Unique user identifier 3 "first_name": "John", // User's given name 4 "last_name": "Doe", // User's family name 5 "name": "John Doe", // Full name for UI display 6 "locale": "en-US", // User's language and region preference 7 "email_verified": true, // Whether the email address has been confirmed 8 "phone_number": "+14155552671", // Contact phone number 9 "metadata": { }, // Additional, non-structured user data 10 "custom_attributes": { 11 "pin_number": "123456" 12 } 13 } ``` Custom attributes are user profile extensions that can be precisely configured to meet your application’s unique needs. For example, as a logistics platform, you might define custom attributes to capture critical operational details like delivery ZIP codes, service zones, or fleet vehicle specifications that apply all your users. ## Map profile attributes to identity providers [Section titled “Map profile attributes to identity providers”](#map-profile-attributes-to-identity-providers) When users authenticate through Single Sign-On (SSO) or join an organization, Scalekit can retrieve and transfer user profile information from the identity provider directly to your application via the ID token during the [login completion](/authenticate/fsa/complete-login/) process. Administrators can configure attribute mapping from their identity provider by selecting specific user profile attributes. This mapping supports both standard and custom attributes seamlessly. ## Modify user profile attributes API [Section titled “Modify user profile attributes ”](#modify-user-profile-attributes-) If your application provides a user interface for users to view and modify their profile details directly within the app, the Scalekit API enables seamless profile attribute updates. * cURL ```sh 1 curl -L -X PATCH '/api/v1/users/' \ 2 -H 'Content-Type: application/json' \ 3 -H 'Authorization: Bearer ...2QA' \ 4 -d '{ 5 "user_profile": { 6 "custom_attributes": { 7 "zip_code": "90210" 8 } 9 } 10 }' ``` * Node.js Update user profile with custom attributes ```javascript 1 // Use case: Update user profile with a custom zip code attribute 2 await scalekit.user.updateUser("", { 3 userProfile: { 4 customAttributes: { 5 zip_code: "11120", 6 }, 7 firstName: "John", 8 lastName: "Doe", 9 locale: "en-US", 10 name: "John Michael Doe", 11 phoneNumber: "+14155552671" 12 } 13 }); ``` * Python Update user profile with custom attributes ```python 1 # Use case: Update user profile with a custom zip code attribute 2 scalekit.user.update_user( 3 "", 4 user_profile={ 5 "custom_attributes": { 6 "zip_code": "11120" 7 }, 8 "first_name": "John", 9 "last_name": "Doe", 10 "locale": "en-US", 11 "name": "John Michael Doe", 12 "phone_number": "+14155552671" 13 } 14 ) ``` * Go Update user profile with custom attributes ```go 1 // Use case: Update user profile with a custom zip code attribute 2 updateUser := &usersv1.UpdateUser{ 3 UserProfile: &usersv1.UpdateUserProfile{ 4 CustomAttributes: map[string]string{ 5 "zip_code": "11120", 6 }, 7 FirstName: "John", 8 LastName: "Doe", 9 Locale: "en-US", 10 Name: "John Michael Doe", 11 PhoneNumber: "+14155552671", 12 }, 13 } 14 15 updatedUser, err := scalekitClient.User().UpdateUser(ctx, "", updateUser) ``` * Java Update user profile with custom attributes ```java 1 // Use case: Update user profile with a custom zip code attribute 2 UpdateUser updateUser = UpdateUser.newBuilder() 3 .setUserProfile( 4 UpdateUserProfile.newBuilder() 5 .putCustomAttributes("zip_code", "11120") 6 .setFirstName("John") 7 .setLastName("Doe") 8 .setLocale("en-US") 9 .setName("John Michael Doe") 10 .setPhoneNumber("+14155552671") 11 .build()) 12 .build(); 13 14 UpdateUserRequest updateReq = UpdateUserRequest.newBuilder() 15 .setUser(updateUser) 16 .build(); 17 18 User updatedUser = scalekitClient.users().updateUser("", updateReq); ``` ## Link your system identifiers & metadata [Section titled “Link your system identifiers & metadata”](#link-your-system-identifiers--metadata) Beyond user profile attributes, you can link your systems with Scalekit to easily map, identify and store more context about organizations and users. This may be helpful when: * You are migrating from an existing system and need to keep your existing identifiers * You are integrating with multiple platforms and need to maintain data consistency * You need to simplify integration by avoiding complex ID mapping between your systems and Scalekit ## Organization external IDs for system integration [Section titled “Organization external IDs for system integration”](#organization-external-ids-for-system-integration) External IDs let you identify organizations using your own identifiers instead of Scalekit’s generated IDs. This is essential when migrating from existing systems or integrating with multiple platforms. 1. #### Set external IDs during organization creation [Section titled “Set external IDs during organization creation”](#set-external-ids-during-organization-creation) Include your system’s identifier when creating organizations to maintain consistent references across your infrastructure. * Node.js Create organization with external ID ```javascript 1 // During user signup or organization creation 2 const { organization } = await scalekit.organization.createOrganization('Acme Corporation', { 3 externalId: 'CUST-12345-ACME' // Your customer ID in your database 4 }); 5 6 console.log('Organization created:', organization.id); 7 console.log('Your ID:', organization.externalId); ``` * Python Create organization with external ID ```python 1 from scalekit.v1.organizations.organizations_pb2 import CreateOrganization 2 3 # During user signup or organization creation 4 organization = CreateOrganization( 5 display_name='Acme Corporation', 6 external_id='CUST-12345-ACME' # Your customer ID in your database 7 ) 8 response = scalekit_client.organization.create_organization(organization=organization) 9 created_organization = response[0].organization 10 11 print(f'Organization created: {created_organization.id}') 12 print(f'Your ID: {created_organization.external_id}') ``` * Go Create organization with external ID ```go 1 // During user signup or organization creation 2 resp, err := scalekitClient.Organization().CreateOrganization(ctx, "Acme Corporation", scalekit.CreateOrganizationOptions{ 3 ExternalId: "CUST-12345-ACME", // Your customer ID in your database 4 }) 5 if err != nil { 6 log.Fatal(err) 7 } 8 9 org := resp.GetOrganization() 10 fmt.Printf("Organization created: %s\n", org.GetId()) 11 fmt.Printf("Your ID: %s\n", org.GetExternalId()) ``` * Java Create organization with external ID ```java 1 // During user signup or organization creation 2 CreateOrganization createOrg = CreateOrganization.newBuilder() 3 .setDisplayName("Acme Corporation") 4 .setExternalId("CUST-12345-ACME") // Your customer ID in your database 5 .build(); 6 7 Organization organization = scalekitClient.organizations().create(createOrg); 8 9 System.out.println("Organization created: " + organization.getId()); 10 System.out.println("Your ID: " + organization.getExternalId()); ``` 2. ### Find organizations using your IDs [Section titled “Find organizations using your IDs”](#find-organizations-using-your-ids) Use external IDs to quickly locate organizations when processing webhooks, handling customer support requests, or syncing data between systems. * Node.js Find organization by external ID ```javascript 1 // When processing a webhook or customer update 2 const customerId = 'CUST-12345-ACME'; // From your webhook payload 3 4 const { organization } = await scalekit.organization.getOrganizationByExternalId(customerId); 5 6 if (organization) { 7 console.log('Found organization:', organization.displayName); 8 // Process organization updates, sync data, etc. 9 } ``` * Python Find organization by external ID ```python 1 # When processing a webhook or customer update 2 customer_id = 'CUST-12345-ACME' # From your webhook payload 3 4 response = scalekit_client.organization.get_organization_by_external_id(customer_id) 5 organization = response[0].organization 6 7 if organization: 8 print(f'Found organization: {organization.display_name}') 9 # Process organization updates, sync data, etc. ``` * Go Find organization by external ID ```go 1 // When processing a webhook or customer update 2 customerId := "CUST-12345-ACME" // From your webhook payload 3 4 resp, err := scalekitClient.Organization().GetOrganizationByExternalId(ctx, customerId) 5 if err != nil { 6 log.Printf("Error finding organization: %v", err) 7 return 8 } 9 10 org := resp.GetOrganization() 11 if org != nil { 12 fmt.Printf("Found organization: %s\n", org.GetDisplayName()) 13 // Process organization updates, sync data, etc. 14 } ``` * Java Find organization by external ID ```java 1 // When processing a webhook or customer update 2 String customerId = "CUST-12345-ACME"; // From your webhook payload 3 4 Organization organization = scalekitClient.organizations().getByExternalId(customerId); 5 6 if (organization != null) { 7 System.out.println("Found organization: " + organization.getDisplayName()); 8 // Process organization updates, sync data, etc. 9 } ``` 3. ### Update external IDs when needed [Section titled “Update external IDs when needed”](#update-external-ids-when-needed) If your customer IDs change or you need to migrate identifier formats, you can update external IDs for existing organizations. * Node.js Update external ID ```javascript 1 const { organization: updatedOrg } = await scalekit.organization.updateOrganization(organizationId, { 2 externalId: 'NEW-CUST-12345-ACME' 3 }); 4 5 console.log('External ID updated:', updatedOrg.externalId); ``` * Python Update external ID ```python 1 from scalekit.v1.organizations.organizations_pb2 import UpdateOrganization 2 3 update_organization = UpdateOrganization(external_id='NEW-CUST-12345-ACME') 4 response = scalekit_client.organization.update_organization( 5 organization_id=organization_id, organization=update_organization 6 ) 7 updated_org = response[0].organization 8 9 print(f'External ID updated: {updated_org.external_id}') ``` * Go Update external ID ```go 1 newExternalId := "NEW-CUST-12345-ACME" 2 resp, err := scalekitClient.Organization().UpdateOrganization(ctx, organizationId, &organizationsv1.UpdateOrganization{ 3 ExternalId: &newExternalId, 4 }) 5 if err != nil { 6 log.Fatal(err) 7 } 8 9 updatedOrg := resp.GetOrganization() 10 fmt.Printf("External ID updated: %s\n", updatedOrg.GetExternalId()) ``` * Java Update external ID ```java 1 UpdateOrganization updateOrg = UpdateOrganization.newBuilder() 2 .setExternalId("NEW-CUST-12345-ACME") 3 .build(); 4 5 Organization updatedOrg = scalekitClient.organizations().updateById(organizationId, updateOrg); 6 7 System.out.println("External ID updated: " + updatedOrg.getExternalId()); ``` ## User external IDs and metadata [Section titled “User external IDs and metadata”](#user-external-ids-and-metadata) Just as organizations need external identifiers, users often require integration with existing systems. User external IDs and metadata work similarly to organization identifiers, enabling you to link Scalekit users with your CRM, HR systems, and other business applications. ### When to use user external IDs and metadata [Section titled “When to use user external IDs and metadata”](#when-to-use-user-external-ids-and-metadata) **External IDs** link Scalekit users to your existing systems: * Reference users in your database, CRM, or billing system * Maintain consistent user identification across multiple platforms * Enable easy data synchronization and lookups **Metadata** stores additional user attributes: * Organizational information (department, location, role level) * Business context (territory, quota, access permissions) * Integration data (external system IDs, custom properties) ### Set user external IDs and metadata during user creation [Section titled “Set user external IDs and metadata during user creation”](#set-user-external-ids-and-metadata-during-user-creation) * Node.js Create user with external ID and metadata ```diff 1 // Use case: Create user during system migration or bulk import with existing system references 2 const { user } = await scalekit.user.createUserAndMembership("", { 3 email: "john.doe@company.com", 4 externalId: "SALESFORCE-003921", 5 metadata: { 6 department: "Sales", 7 employeeId: "EMP-002", 8 territory: "West Coast", 9 quota: 150000, 10 crmAccountId: "ACC-789", 11 hubspotContactId: "12345", 12 + }, 13 userProfile: { 14 firstName: "John", 15 lastName: "Doe", 16 }, 17 sendInvitationEmail: true, 18 }); ``` * Python Create user with external ID and metadata ```diff 1 # Use case: Create user during system migration or bulk import with existing system references 2 user_response = scalekit.user.create_user_and_membership( 3 "", 4 +email="john.doe@company.com", 5 +external_id="SALESFORCE-003921", 6 +metadata={ 7 "department": "Sales", 8 "employee_id": "EMP-002", 9 "territory": "West Coast", 10 "quota": 150000, 11 "crm_account_id": "ACC-789", 12 "hubspot_contact_id": "12345" 13 }, 14 user_profile={ 15 "first_name": "John", 16 "last_name": "Doe" 17 }, 18 send_invitation_email=True 19 ) ``` * Go Create user with external ID and metadata ```diff 1 // Use case: Create user during system migration or bulk import with existing system references 2 newUser := &usersv1.CreateUser{ 3 Email: "john.doe@company.com", 4 +ExternalId: "SALESFORCE-003921", 5 +Metadata: map[string]string{ 6 "department": "Sales", 7 "employee_id": "EMP-002", 8 "territory": "West Coast", 9 "quota": "150000", 10 "crm_account_id": "ACC-789", 11 "hubspot_contact_id": "12345", 12 + }, 13 UserProfile: &usersv1.CreateUserProfile{ 14 FirstName: "John", 15 LastName: "Doe", 16 }, 17 } 18 userResp, err := scalekitClient.User().CreateUserAndMembership( 19 ctx, 20 "", 21 newUser, 22 true, // sendInvitationEmail 23 ) ``` * Java Create user with external ID and metadata ```diff 1 // Use case: Create user during system migration or bulk import with existing system references 2 CreateUser createUser = CreateUser.newBuilder() 3 .setEmail("john.doe@company.com") 4 + .setExternalId("SALESFORCE-003921") 5 + .putMetadata("department", "Sales") 6 + .putMetadata("employee_id", "EMP-002") 7 + .putMetadata("territory", "West Coast") 8 + .putMetadata("quota", "150000") 9 + .putMetadata("crm_account_id", "ACC-789") 10 + .putMetadata("hubspot_contact_id", "12345") 11 + .setUserProfile( 12 +CreateUserProfile.newBuilder() 13 .setFirstName("John") 14 .setLastName("Doe") 15 .build()) 16 .build(); 17 18 CreateUserAndMembershipRequest createUserReq = CreateUserAndMembershipRequest.newBuilder() 19 .setUser(createUser) 20 .setSendInvitationEmail(true) 21 .build(); 22 23 CreateUserAndMembershipResponse userResp = scalekitClient.users() 24 .createUserAndMembership("", createUserReq); ``` ### Update user external IDs and metadata for existing users [Section titled “Update user external IDs and metadata for existing users”](#update-user-external-ids-and-metadata-for-existing-users) * Node.js Update user external ID and metadata ```diff 1 // Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call 2 const updatedUser = await scalekit.user.updateUser("", { 3 externalId: "SALESFORCE-003921", 4 metadata: { 5 department: "Sales", 6 employeeId: "EMP-002", 7 territory: "West Coast", 8 quota: 150000, 9 crmAccountId: "ACC-789", 10 hubspotContactId: "12345", 11 + }, 12 }); ``` * Python Update user external ID and metadata ```diff 1 # Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call 2 updated_user = scalekit.user.update_user( 3 "", 4 +external_id="SALESFORCE-003921", 5 +metadata={ 6 "department": "Sales", 7 "employee_id": "EMP-002", 8 "territory": "West Coast", 9 "quota": 150000, 10 "crm_account_id": "ACC-789", 11 "hubspot_contact_id": "12345" 12 } 13 ) ``` * Go Update user external ID and metadata ```go 1 // Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call 2 updateUser := &usersv1.UpdateUser{ 3 ExternalId: "SALESFORCE-003921", 4 Metadata: map[string]string{ 5 "department": "Sales", 6 "employee_id": "EMP-002", 7 "territory": "West Coast", 8 "quota": "150000", 9 "crm_account_id": "ACC-789", 10 "hubspot_contact_id": "12345", 11 }, 12 } 13 updatedUser, err := scalekitClient.User().UpdateUser( 14 ctx, 15 "", 16 updateUser, 17 ) ``` * Java Update user external ID and metadata ```java 1 // Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call 2 UpdateUser updateUser = UpdateUser.newBuilder() 3 .setExternalId("SALESFORCE-003921") 4 .putMetadata("department", "Sales") 5 .putMetadata("employee_id", "EMP-002") 6 .putMetadata("territory", "West Coast") 7 .putMetadata("quota", "150000") 8 .putMetadata("crm_account_id", "ACC-789") 9 .putMetadata("hubspot_contact_id", "12345") 10 .build(); 11 12 UpdateUserRequest updateReq = UpdateUserRequest.newBuilder() 13 .setUser(updateUser) 14 .build(); 15 16 User updatedUser = scalekitClient.users().updateUser("", updateReq); ``` ### Find users by external ID [Section titled “Find users by external ID”](#find-users-by-external-id) * Node.js Find user by external ID ```javascript 1 // Use case: Look up Scalekit user when you have your system's user ID 2 const user = await scalekit.user.getUserByExternalId("", "SALESFORCE-003921"); 3 console.log(`Found user: ${user.email} with ID: ${user.id}`); ``` * Python Find user by external ID ```python 1 # Use case: Look up Scalekit user when you have your system's user ID 2 user = scalekit.user.get_user_by_external_id("", "SALESFORCE-003921") 3 print(f"Found user: {user['email']} with ID: {user['id']}") ``` * Go Find user by external ID ```go 1 // Use case: Look up Scalekit user when you have your system's user ID 2 user, err := scalekitClient.User().GetUserByExternalId( 3 ctx, 4 "", 5 "SALESFORCE-003921", 6 ) 7 if err != nil { 8 log.Printf("User not found: %v", err) 9 } else { 10 fmt.Printf("Found user: %s with ID: %s\n", user.Email, user.Id) 11 } ``` * Java Find user by external ID ```java 1 // Use case: Look up Scalekit user when you have your system's user ID 2 try { 3 GetUserByExternalIdResponse response = scalekitClient.users() 4 .getUserByExternalId("", "SALESFORCE-003921"); 5 6 User user = response.getUser(); 7 System.out.printf("Found user: %s with ID: %s%n", user.getEmail(), user.getId()); 8 } catch (Exception e) { 9 System.err.println("User not found: " + e.getMessage()); 10 } ``` This integration approach maintains consistent user identity across your system architecture while letting you choose the source of truth for authentication and authorization. Both user and organization external IDs work together to provide complete system integration capabilities. --- # DOCUMENT BOUNDARY --- # Delete users and organizations > Trigger deletions and let Scalekit handle sessions, memberships, and cleanup automatically Properly deleting users and organizations is essential for security and regulatory compliance. Whether a user departs or an entire organization must be removed, it’s important to have reliable deletion processes in place. This guide shows you how to implement deletion for both users and organizations. Provide a feature for administrators to permanently delete a user account. This is useful for handling user account closures, GDPR deletion requests, or cleaning up test accounts. 1. ## Delete a user [Section titled “Delete a user”](#delete-a-user) Call the `deleteUser` method with the user’s ID: * Node.js Delete a user permanently ```javascript 1 // Use case: User account closure, GDPR deletion requests, or cleaning up test accounts 2 await scalekit.user.deleteUser("usr_123"); ``` * Python Delete a user permanently ```python 1 # Use case: User account closure, GDPR deletion requests, or cleaning up test accounts 2 scalekit_client.users.delete_user( 3 user_id="usr_123" 4 ) ``` * Go Delete a user permanently ```go 1 // Use case: User account closure, GDPR deletion requests, or cleaning up test accounts 2 if err := scalekitClient.User().DeleteUser(ctx, "usr_123"); err != nil { 3 panic(err) 4 } ``` * Java Delete a user permanently ```java 1 // Use case: User account closure, GDPR deletion requests, or cleaning up test accounts 2 scalekitClient.users().deleteUser("usr_123"); ``` When you delete a user, Scalekit performs the following actions: * Terminates all of the user’s active sessions. * Removes all of the user’s organization memberships. * Permanently deletes the user account. 2. ## Delete an organization [Section titled “Delete an organization”](#delete-an-organization) Provide a feature for users to delete organizations they own. This is useful for company closures, account restructuring, or removing test organizations. Call the `deleteOrganization` method with the organization’s ID: * Node.js Delete an organization permanently ```javascript 1 // Use case: Company closure, account restructuring, or removing test organizations 2 await scalekit.organization.deleteOrganization(organizationId); ``` * Python Delete an organization permanently ```python 1 # Use case: Company closure, account restructuring, or removing test organizations 2 scalekit_client.organization.delete_organization(organization_id) ``` * Go Delete an organization permanently ```go 1 // Use case: Company closure, account restructuring, or removing test organizations 2 err := scalekitClient.Organization().DeleteOrganization( 3 ctx, 4 organizationId 5 ) 6 if err != nil { 7 panic(err) 8 } ``` * Java Delete an organization permanently ```java 1 // Use case: Company closure, account restructuring, or removing test organizations 2 scalekitClient.organizations().deleteById(organizationId); ``` When you delete an organization, Scalekit performs the following actions: * Terminates active sessions for all organization members. * Removes all user memberships from the organization. * Permanently removes all organization data and settings. * **Cascading deletion**: If a user is a member of only this organization, their account is also permanently deleted. * Users who are members of other organizations retain their accounts and access. Permanent deletion cannot be undone * Ensure you have appropriate backups and audit trails in your system before deleting a user. * If your organization has data retention policies, consider implementing a soft delete. Schedule the permanent deletion for a future date (e.g., 30-60 days) to allow for data backup and user notifications. --- # DOCUMENT BOUNDARY --- # Configure email domain rules > Set up allowed domains for organization auto-join and configure restrictions for generic and disposable email sign-ups Email domain rules control how users join your application in two ways: by restricting who can sign up and by enabling automatic organization membership for trusted domains. These rules help maintain data quality, prevent abuse, and streamline onboarding for enterprise customers. Sign-up restrictions block registrations and invitations from generic email providers (like Gmail or Outlook) and disposable email services, ensuring your user base consists of verified business contacts. Allowed email domains enable users with matching email addresses to automatically join organizations through the organization switcher, reducing manual invitation overhead. Together, these features give you fine-grained control over user addition, blocking unwanted sign-ups while facilitating seamless access for legitimate users from trusted domains. ## Set up sign-up restrictions [Section titled “Set up sign-up restrictions”](#set-up-sign-up-restrictions) Sign-up restrictions help you maintain data quality and prevent abuse by controlling who can create accounts in your application. This is particularly important for B2B applications where you need to ensure users have legitimate business email addresses rather than personal or temporary accounts. These restrictions automatically block registrations and invitations from two types of email addresses: * **Generic email domains** - Public email providers like `@gmail.com`, `@outlook.com`, or `@yahoo.com` that anyone can use * **Disposable email addresses** - Temporary email services often used for spam, trial abuse, or avoiding accountability When enabled, these restrictions apply to both direct signups and organization invitations, ensuring consistent policy enforcement across your application. This prevents users from creating multiple trial accounts, maintains clean analytics, and ensures your user base consists of verified business contacts. The following diagram illustrates how sign-up restrictions work: ### How restrictions affect invitations [Section titled “How restrictions affect invitations”](#how-restrictions-affect-invitations) * Any user with a disposable email domain cannot sign up to create a new organization and cannot be invited to any existing organization. * Any user with a public email domain cannot sign up to create a new organization and cannot be invited to any existing organization. ### Set sign-up restrictions [Section titled “Set sign-up restrictions”](#set-sign-up-restrictions) 1. ### Navigate to sign-up restrictions settings [Section titled “Navigate to sign-up restrictions settings”](#navigate-to-sign-up-restrictions-settings) Go to **Dashboard > Authentication > General** and locate the sign-up restrictions section. 2. ### Configure restriction options [Section titled “Configure restriction options”](#configure-restriction-options) Toggle the following options based on what suits your application: * **Block disposable email domains**: Prevents temporary/disposable email addresses from signing up or being invited * **Block public email domains**: Prevents generic email providers like Gmail, Outlook, Yahoo from creating organizations ![Authentication General tab showing Sign-up Settings with toggles to block sign-up for public email domains and disposable email domains](/.netlify/images?url=_astro%2Fui.D6G2x64L.png\&w=2858\&h=1611\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ### Save your settings [Section titled “Save your settings”](#save-your-settings) Click **Save** to apply the restrictions. Changes take effect immediately for all new signups and invitations. ## Configure allowed email domains [Section titled “Configure allowed email domains”](#configure-allowed-email-domains) Allowed email domains lets organization admins define trusted domains for their organization. When a user signs in or signs up with a matching email domain, Scalekit suggests the user to join that organization in the **organization switcher** so the user can join the organization with one click. This feature is authentication-method agnostic: regardless of whether a user authenticates via SSO, social login, or passwordless authentication, organization options are suggested based on their email domain. When a user signs up or signs in, Scalekit will automatically: 1. **Match email domains** - Check if the user’s email domain matches configured allowed domains for any organization. 2. **Suggest organization options** - Show the user available organizations they can join through an organization switcher. 3. **Enable user choice** - Allow users to decide which of the suggested organizations they want to join. 4. **Create organization membership** - Automatically add the user to their selected organization. ### Manage allowed email domains in Scalekit Dashboard [Section titled “Manage allowed email domains in Scalekit Dashboard”](#manage-allowed-email-domains-in-scalekit-dashboard) Allowed email domains can be configured for an organization through the Scalekit Dashboard. ![Organization settings page with the Allowed email domains section listing acmecorp.com and an Add domain button](/.netlify/images?url=_astro%2Fdashboard.Cf5i9h8I.png\&w=2938\&h=1588\&dpl=6aaa70ad2ea7b40008ad2afd) 1. Navigate to **Organizations** and **select an organization**. 2. Navigate to **Overview** > **User Management** > **Allowed email domains**. 3. Add or edit allowed email domains for automatic suggestions/provisioning. ### Manage allowed email domains API [Section titled “Manage allowed email domains ”](#manage-allowed-email-domains-) Configure allowed email domains for an organization programmatically through the Scalekit API. Before proceeding, complete the steps in the [installation guide](/authenticate/set-up-scalekit/). * cURL Register, list, get, and delete allowed email domains ```sh # 1. Register an allowed email domain # Use case: Restrict user registration to specific company domains for B2B applications curl 'https:///api/v1/organizations/{organization_id}/domains' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "domain": "customerdomain.com", "domain_type": "ALLOWED_EMAIL_DOMAIN" }' # 2. List all registered allowed email domains # Use case: Display domain restrictions in admin dashboard or verify current settings curl 'https:///api/v1/organizations/{organization_id}/domains' # 3. Get details of a specific domain # Use case: Verify domain configuration or retrieve domain metadata curl 'https:///api/v1/organizations/{organization_id}/domains/{domain_id}' # 4. Delete an allowed email domain # Use case: Remove domain restrictions or clean up unused configurations curl 'https:///api/v1/organizations/{organization_id}/domains/{domain_id}' \ --request DELETE ``` * Nodejs Register, list, get, and delete allowed email domains ```js 1 // 1. Register an allowed email domain 2 // Use case: Restrict user registration to specific company domains for B2B applications 3 const newDomain = await scalekit.createDomain("org-123", "customerdomain.com", { 4 domainType: "ALLOWED_EMAIL_DOMAIN", 5 }); 6 7 // 2. List all registered allowed email domains 8 // Use case: Display domain restrictions in admin dashboard or verify current settings 9 const domains = await client.domain.listDomains(organizationId); 10 11 // 3. Get details of a specific domain 12 // Use case: Verify domain configuration or retrieve domain metadata 13 const domain = await client.domain.getDomain(organizationId, domainId); 14 15 // 4. Delete an allowed email domain 16 // Use case: Remove domain restrictions or clean up unused configurations 17 // Caution: Deletion is permanent and may affect user access 18 await client.domain.deleteDomain(organizationId, domainId); ``` --- # DOCUMENT BOUNDARY --- # Hosted UI widgets > Redirect users to a branded self-serve portal for organization settings, member management, SSO, SCIM, domains, and user profiles. Redirect signed-in users from your application to Hosted UI widgets at `/ui/` so their workspace administrators can self-manage organizations, members, single sign-on (SSO), SCIM provisioning, domains, and profiles. For example, add a link in your app’s settings or account area. Scalekit will use the active session and show users their workspace automatically. Hosted UI widgets URL ```sh /ui/ # https://your-app-env.scalekit.com/ui/ ``` ## When to use Hosted UI widgets [Section titled “When to use Hosted UI widgets”](#when-to-use-hosted-ui-widgets) Use Hosted UI widgets when you want customers to self-manage their organizations and accounts without you building custom UIs. * **Advantages**: Enterprise customers can self-serve member management, SSO setup, SCIM provisioning, domain verification, session policy, and their own profiles. Permissions and organization features are handled automatically. The portal stays up to date with new Scalekit capabilities. * **Trade-offs**: Customers leave your application UI and work in Scalekit-hosted pages. Branding follows your shared application customization settings. You send users to `/ui/`; they use portal navigation to open individual modules. If you need a shareable link or iframe embed for enterprise IT administrators to configure SSO, SCIM, and organization domain verification, use the [Admin portal](/guides/admin-portal/) instead. The Admin portal supports only those three modules. Hosted UI widgets are the better fit for signed-in users who open self-serve settings from inside your product. ## Organization widgets [Section titled “Organization widgets”](#organization-widgets) Organization widgets let your customers manage their organization’s settings, members, and configurations. These widgets are access-controlled using Scalekit permissions and the features enabled for the organization. A widget appears only if the user has the required permissions and the organization has the corresponding feature enabled. ### Manage organization settings [Section titled “Manage organization settings”](#manage-organization-settings) Your customers can view and manage their organization profile, including allowed email domains. Navigate to **Organization settings** to update organization details. ![Organization settings widget showing the organization name field and a list of allowed email domains](/.netlify/images?url=_astro%2Forg_settings.XshZN6sS.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) ### Manage organization members [Section titled “Manage organization members”](#manage-organization-members) Your customers can view organization members, invite new members, manage roles, and remove members from the organization. The **Member management** widget provides a complete view of their team. ![Member management widget listing organization users with their roles and active status, plus an Invite User button](/.netlify/images?url=_astro%2Forg_member.pe4fgTMu.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) ### Configure SSO for the organization [Section titled “Configure SSO for the organization”](#configure-sso-for-the-organization) Your customers can set up and manage Single Sign-On for their organization. The widget includes a setup guide tailored to their identity provider, making it easy to connect their SSO connection. ![Single Sign-On widget prompting the user to choose an identity provider such as Okta, OneLogin, Google Workspace, or Entra ID](/.netlify/images?url=_astro%2Forg_sso.IHoRc3E6.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) ### Configure SCIM for the organization [Section titled “Configure SCIM for the organization”](#configure-scim-for-the-organization) Your customers can set up and manage SCIM provisioning for their organization. The widget includes a setup guide tailored to their identity provider to automate user and group provisioning. ![SCIM provisioning widget prompting the user to select a directory provider such as Okta, OneLogin, Google Workspace, or Entra ID](/.netlify/images?url=_astro%2Forg_scim.CBDzga3B.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) ### Verify organization domains [Section titled “Verify organization domains”](#verify-organization-domains) Your customers can add and verify the domains they own, enabling Home Realm Discovery and SCIM provisioning for their organization. [Learn more about organization domains](/authenticate/manage-users-orgs/organization-domains/). After entering a domain, the widget displays the DNS TXT record to publish. Scalekit verifies ownership in the background and marks the domain as verified once the record propagates. ![Domain verification via Hosted UI widgets](/.netlify/images?url=_astro%2F2026-05-26-19-06-40.DKn_DLNP.png\&w=2932\&h=1598\&dpl=6aaa70ad2ea7b40008ad2afd) ### Manage session policy [Section titled “Manage session policy”](#manage-session-policy) Your customers can view and configure their organization’s session policy, setting custom absolute and idle session timeouts that override your application defaults. Scalekit always enforces the stricter of the two. ![Session policy widget with Application and Custom options selected, showing absolute and idle session timeout settings](/.netlify/images?url=_astro%2F2026-05-21-17-12-14.OQW71QKW.png\&w=2920\&h=1570\&dpl=6aaa70ad2ea7b40008ad2afd) ## User widgets [Section titled “User widgets”](#user-widgets) User widgets let your customers manage their personal profile and security settings. These widgets are accessible to all authenticated users and are not controlled by organization features or Scalekit permissions. ### Manage profile [Section titled “Manage profile”](#manage-profile) Your customers can view and manage their personal profile information, including their name, email, and other account details. ![My Account widget showing editable first name and last name fields and a verified email address](/.netlify/images?url=_astro%2Fuser_profile.DF85cQEC.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) ### Manage security [Section titled “Manage security”](#manage-security) Your customers can register and manage passkeys, view active sessions, and revoke sessions. The **User security** widget helps them maintain account security. ![User security widget showing a registered passkey and a list of active sessions with options to revoke them](/.netlify/images?url=_astro%2Fuser_security.B5SWg3po.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) ## Access management [Section titled “Access management”](#access-management) Hosted UI widgets enforce access using **Scalekit permissions**. You can map these permissions to any application roles assigned to the end user. When a user accesses Hosted UI widgets, Scalekit checks their permissions and shows the available widgets. | Permission | Purpose | | ------------------------------ | ------------------------------------------------------ | | `sk_org_settings_read` | View organization profile and settings | | `sk_org_settings_manage` | View and modify organization profile and settings | | `sk_org_users_read` | View users in an organization | | `sk_org_users_invite` | Invite new users to an organization | | `sk_org_users_delete` | Remove users from an organization | | `sk_org_users_role_change` | Change roles of users in an organization | | `sk_org_sso_read` | View SSO configuration for an organization | | `sk_org_sso_manage` | View and modify SSO configuration for an organization | | `sk_org_scim_read` | View SCIM configuration for an organization | | `sk_org_scim_manage` | View and modify SCIM configuration for an organization | | `sk_org_session_policy_read` | View session policy for an organization | | `sk_org_session_policy_manage` | View and manage session policy for an organization | ## Branding and customization [Section titled “Branding and customization”](#branding-and-customization) Hosted UI widgets use your application [branding](/fsa/guides/login-page-branding/) so the portal looks like an extension of your app. The same customization settings apply across hosted experiences, including the login page and [Admin portal](/guides/admin-portal/). You can also apply [organization branding](/fsa/guides/organization-branding/) where that feature is enabled. You can change the Hosted UI widgets URL to match your application URL by setting up a [custom domain](/guides/custom-domain/). ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) --- # DOCUMENT BOUNDARY --- # Provision user accounts Just-In-Time (JIT) > Turn first-time SSO logins into instant, secure access Organizations where the SSO connection is set up, the enterprise users maybe yet to sign up on your application before they can access your application. Scalekit can automatically provision the user accounts as they sign in through SSO for the first time and creates a membership with an organization instantly. Your app will receive the user’s profile and organization membership details. This is called Just-in-time (JIT) provisioning. This eliminates the need for manual invitations and allows users to access your application immediately after authenticating with their identity provider. JIT is enabled by default once you [integrated](/authenticate/fsa/quickstart/) and enabled [the SSO connection](/authenticate/auth-methods/enterprise-sso/). ## Manage JIT provisioning [Section titled “Manage JIT provisioning”](#manage-jit-provisioning) Manage JIT provisioning settings for each organization through the Scalekit Dashboard. Register organization domains to enable automatic user creation, and configure whether Scalekit should sync user attributes every time users sign in through SSO. 1. ### Register organization owned domains [Section titled “Register organization owned domains”](#register-organization-owned-domains) Register email domains for your organization to enable JIT provisioning. JIT provisioning only works for users whose email domain matches one of the organization’s registered [Organization domains](/authenticate/manage-users-orgs/organization-domains/). This ensures that only verified members of the organization can be automatically provisioned. **Contractors and external users** with non-matching domains (for eg, `joe@ext.yourapp.com`) cannot be automatically provisioned. These users must be [manually invited](/fsa/guides/user-invitations/) to join the organization. This ensures that unauthorized users cannot obtain access automatically. 2. ### Toggle JIT provisioning on or off [Section titled “Toggle JIT provisioning on or off”](#toggle-jit-provisioning-on-or-off) **JIT provisioning is enabled by default** once you [integrated](/authenticate/fsa/quickstart/) and enabled [the SSO connection](/authenticate/auth-methods/enterprise-sso/). You can toggle JIT provisioning on or off from the Scalekit Dashboard. Go to **Organizations** and select the target organization > **Single Sign On** → **Settings** → **Just-in-time provisioning** section. ![Single Sign On Settings tab for an organization with the Just-in-time provisioning toggle enabled](/.netlify/images?url=_astro%2Fjit-provisioning.CWBROiBA.png\&w=2934\&h=1588\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ### Keep the user profile in sync with the identity provider [Section titled “Keep the user profile in sync with the identity provider”](#keep-the-user-profile-in-sync-with-the-identity-provider) Enable **Sync user attributes during login** to keep user profiles updated. When enabled, Scalekit updates the user’s profile using attributes from the identity provider each time they authenticate. This keeps the user’s profile in Scalekit aligned with the external Identity Provider. ![Single Sign On Settings tab highlighting the Sync user attributes during login toggle below the Just-in-time provisioning setting](/.netlify/images?url=_astro%2Fsync-user-profile.DW9qgfGm.png\&w=2932\&h=1580\&dpl=6aaa70ad2ea7b40008ad2afd) 4. ### Using self-service Admin Portal for organization admins [Section titled “Using self-service Admin Portal for organization admins”](#using-self-service-admin-portal-for-organization-admins) Your customers (organization admins) can manage JIT provisioning settings through the Admin Portal, including registering organization-owned domains, toggling JIT provisioning on or off, and keeping user profiles in sync with the identity provider. [Generate and share Admin Portal](/guides/admin-portal/) with your customers to set up SSO for their organization. Your end customer can manage the JIT configuration in **Admin portal** > **Single Sign On** > **Settings** > **Just-in-time provisioning** section. ## Common JIT provisioning scenarios [Section titled “Common JIT provisioning scenarios”](#common-jit-provisioning-scenarios) --- # DOCUMENT BOUNDARY --- # Merge user identities > Scalekit automatically merges user identities from different authentication methods, ensuring a single user profile and preventing duplicate accounts Users can sign into your application using different authentication methods. A user might authenticate with a passwordless method today and LinkedIn OAuth tomorrow. Scalekit automatically merges these identities into a single user profile. This prevents duplicate accounts and ensures a unified experience. Identity linking is how Scalekit safely deduplicates authentication methods across identity providers. Scalekit uses the **email address** as the unique identifier and access to the email inbox as the source of truth. When users prove access to their email inbox through any authentication method, Scalekit treats this as an identity. Scalekit automatically links multiple identities together using the user’s email address as the source of truth. All authentication methods for the same email address are associated with a single User object. ## Domain verification [Section titled “Domain verification”](#domain-verification) When an organization administrator verifies a domain for their organization through [allowed email domains](/authenticate/manage-users-orgs/email-domain-rules/), they prove they have access to create email inboxes. A **verified domain implies the ability to verify all users with that email domain**. When a domain is verified and an SSO connection is configured, users who sign in through an organization’s identity provider are automatically considered email verified if the domain matches. This reduces friction for your end users while maintaining security. Users who sign in through SSO with an email address that is not a verified domain are not considered verified. These users must go through the email verification process. ## Merge SSO identities [Section titled “Merge SSO identities”](#merge-sso-identities) Users can have multiple authentication methods. Users can also have multiple SSO credentials. This happens when a user works with multiple organizations that each require SSO authentication for all members. There is still only one User object. Users choose which organization’s SSO identity provider to use when authenticating. When users sign in through an SSO identity provider for the first time, Scalekit checks if their email domain is verified. If verified, Scalekit automatically links the SSO credential to the user’s existing account. Email verification safety still applies. When a user signs in for the first time through an SSO identity provider where the user’s email address is not a verified domain, Scalekit asks the user to verify their email before linking the SSO credential to their account. --- # DOCUMENT BOUNDARY --- # Organization domains > Verify ownership of customer domains so Scalekit can route Home Realm Discovery (SSO) and SCIM provisioning to the right organization. An **organization domain** is a domain your customer owns — such as `acmecorp.com`. Proving domain ownership unlocks two key features: * **[Home Realm Discovery (SSO)](/authenticate/auth-methods/enterprise-sso/#identify-and-enforce-sso-for-organization-users)**: When a user signs in with an email address matching a registered domain, Scalekit automatically routes them to that organization’s SSO identity provider. * **[SCIM Provisioning](/authenticate/manage-users-orgs/scim-provisioning/)**: Scalekit only processes SCIM user lifecycle events (create, update, deactivate) for users whose email domain matches a registered organization domain. This ensures only the organization that owns a domain can manage those users. ## Add and verify an organization domain [Section titled “Add and verify an organization domain”](#add-and-verify-an-organization-domain) ### Via Admin portal No-code [Section titled “Via Admin portal ”](#via-admin-portal-) The Admin portal gives the admin of a customer organization a self-serve way to add and verify their domain — without involving your engineering team. This is the recommended approach for production onboarding. 1. ### Enable domain verification for the organization [Section titled “Enable domain verification for the organization”](#enable-domain-verification-for-the-organization) Turn on the `Domain Verification` feature for the organization. You can do this in the Scalekit Dashboard (navigate to **Organizations** → select the organization → **Overview** → toggle **Domain Verification**), or via the API: * cURL Enable domain\_verification feature ```sh curl --request PATCH \ 'https:///api/v1/organizations//settings' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "features": [{ "name": "domain_verification", "enabled": true }] }' ``` * Node.js Enable domain\_verification feature ```ts 1 await scalekit.organization.updateOrganizationSettings(organizationId, { 2 features: [{ name: 'domain_verification', enabled: true }], 3 }); ``` * Python Enable domain\_verification feature ```python 1 scalekit_client.organization.update_organization_settings( 2 organization_id, 3 [{"name": "domain_verification", "enabled": True}], 4 ) ``` * Go Enable domain\_verification feature ```go 1 err = scalekitClient.Organization.UpdateOrganizationSettings( 2 ctx, 3 organizationID, 4 scalekit.OrganizationSettings{ 5 Features: []scalekit.OrganizationSettingsFeature{ 6 {Name: "domain_verification", Enabled: true}, 7 }, 8 }, 9 ) ``` * Java Enable domain\_verification feature ```java 1 scalekitClient.organizations().updateOrganizationSettings( 2 organizationId, 3 List.of(new Feature().setName("domain_verification").setEnabled(true)) 4 ); ``` 2. ### Generate an Admin portal link and embed in your app [Section titled “Generate an Admin portal link and embed in your app”](#generate-an-admin-portal-link-and-embed-in-your-app) Generate an admin portal link and embed in your application: * cURL Generate portal link for domain verification ```sh curl 'https:///api/v1/organizations//portal_links' \ --header 'Authorization: Bearer ' ``` * Node.js Generate portal link for domain verification ```ts 1 const link = await scalekit.organization.generatePortalLink(organizationId); 2 // Redirect the org admin to link.location ``` * Python Generate portal link for domain verification ```python 1 link = scalekit_client.organization.generate_portal_link(organization_id) 2 # Redirect the org admin to link.location ``` * Go Generate portal link for domain verification ```go 1 link, err := scalekitClient.Organization().GeneratePortalLink(ctx, organizationID) 2 // Redirect the org admin to link.Link.Location ``` * Java Generate portal link for domain verification ```java 1 Link link = scalekitClient.organizations().generatePortalLink( 2 organizationId, 3 Arrays.asList(Feature.domain_verification) 4 ); 5 // Redirect the org admin to link.getLocation() ``` 3. ### Organization admin adds the domain and publishes the DNS record [Section titled “Organization admin adds the domain and publishes the DNS record”](#organization-admin-adds-the-domain-and-publishes-the-dns-record) The admin opens the portal link, clicks **Add domain**, and enters their domain name. The portal displays the TXT record to add and verify domain ownership. The admin adds this record in their DNS provider (e.g., Cloudflare, Route 53, GoDaddy). Propagation typically takes a few minutes but can take up to 48 hours. ![Domain verification via admin portal](/.netlify/images?url=_astro%2F2026-05-26-19-01-37.C8CAmZIi.png\&w=2196\&h=1596\&dpl=6aaa70ad2ea7b40008ad2afd) 4. ### Scalekit verifies the DNS record [Section titled “Scalekit verifies the DNS record”](#scalekit-verifies-the-dns-record) Scalekit polls the domain’s DNS automatically. Once the TXT record is detected, the domain status changes to **Verified** and SSO routing and SCIM become active. ### Via Hosted UI widgets No-code [Section titled “Via Hosted UI widgets ”](#via-hosted-ui-widgets-) Turn on the `Domain Verification` feature for the organization. Then redirect end users to [Hosted UI widgets](/authenticate/manage-users-orgs/hosted-widgets/) to manage their organization’s domains. The domain verification flow inside the widget is identical to the Admin portal. For a shareable link or iframe embed aimed at enterprise IT, use the [Admin portal](/guides/admin-portal/). ![Domain verification via Hosted UI widgets](/.netlify/images?url=_astro%2F2026-05-26-19-06-40.DKn_DLNP.png\&w=2932\&h=1598\&dpl=6aaa70ad2ea7b40008ad2afd) ### Via Scalekit Dashboard No-code [Section titled “Via Scalekit Dashboard ”](#via-scalekit-dashboard-) Your team can add organization domains directly from the Scalekit Dashboard, useful for initial setup or when you have already verified ownership through other means. 1. Go to **Dashboard > Organizations** and select the target organization. 2. Navigate to **Overview** > **Organization Domains**. 3. Click **Add domain** and enter the domain name. ![Domain verification via dashboard](/.netlify/images?url=_astro%2F2026-05-26-19-09-32.CbEgDZch.png\&w=2918\&h=1580\&dpl=6aaa70ad2ea7b40008ad2afd) Domains added this way are marked as **Admin-verified**, no DNS verification is required. They become active for SSO routing and SCIM immediately. ### Via API API [Section titled “Via API ”](#via-api-) Add and manage organization domains programmatically. Domains created via the API are also **Admin-verified** by default, no DNS verification is required. Use this when you have already confirmed domain ownership through another process and want to activate SSO routing or SCIM immediately. * cURL Manage organization domains ```sh # 1. Add an organization domain curl 'https:///api/v1/organizations//domains' \ --request POST \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "domain": "acmecorp.com", "domain_type": "ORGANIZATION_DOMAIN" }' # 2. List all organization domains curl 'https:///api/v1/organizations//domains?domain_type=ORGANIZATION_DOMAIN' \ --header 'Authorization: Bearer ' # 3. Get details of a specific domain curl 'https:///api/v1/organizations//domains/' \ --header 'Authorization: Bearer ' # 4. Delete a domain curl 'https:///api/v1/organizations//domains/' \ --request DELETE \ --header 'Authorization: Bearer ' ``` * Node.js Manage organization domains ```ts 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new Scalekit( 4 process.env.SCALEKIT_ENVIRONMENT_URL, 5 process.env.SCALEKIT_CLIENT_ID, 6 process.env.SCALEKIT_CLIENT_SECRET, 7 ); 8 9 // 1. Add an organization domain 10 const newDomain = await scalekit.organization.createDomain(organizationId, { 11 domain: 'acmecorp.com', 12 domainType: 'ORGANIZATION_DOMAIN', 13 }); 14 // newDomain.txtRecordKey and newDomain.txtRecordSecret contain the DNS record values 15 16 // 2. List all organization domains 17 const { domains } = await scalekit.organization.listDomains(organizationId, { 18 domainType: 'ORGANIZATION_DOMAIN', 19 }); 20 21 // 3. Get a specific domain 22 const domain = await scalekit.organization.getDomain(organizationId, domainId); 23 24 // 4. Delete a domain 25 await scalekit.organization.deleteDomain(organizationId, domainId); ``` * Python Manage organization domains ```python 1 from scalekit import Scalekit 2 import os 3 4 scalekit_client = Scalekit( 5 environment_url=os.environ.get("SCALEKIT_ENVIRONMENT_URL"), 6 client_id=os.environ.get("SCALEKIT_CLIENT_ID"), 7 client_secret=os.environ.get("SCALEKIT_CLIENT_SECRET"), 8 ) 9 10 # 1. Add an organization domain 11 new_domain = scalekit_client.organization.create_domain( 12 organization_id, 13 domain="acmecorp.com", 14 domain_type="ORGANIZATION_DOMAIN", 15 ) 16 # new_domain.txt_record_key and new_domain.txt_record_secret contain the DNS record values 17 18 # 2. List all organization domains 19 domains = scalekit_client.organization.list_domains( 20 organization_id, domain_type="ORGANIZATION_DOMAIN" 21 ) 22 23 # 3. Get a specific domain 24 domain = scalekit_client.organization.get_domain(organization_id, domain_id) 25 26 # 4. Delete a domain 27 scalekit_client.organization.delete_domain(organization_id, domain_id) ``` * Go Manage organization domains ```go 1 import ( 2 "context" 3 "os" 4 5 "github.com/scalekit/sdk-go" 6 ) 7 8 scalekitClient := scalekit.New( 9 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 10 os.Getenv("SCALEKIT_CLIENT_ID"), 11 os.Getenv("SCALEKIT_CLIENT_SECRET"), 12 ) 13 14 ctx := context.Background() 15 16 // 1. Add an organization domain 17 newDomain, err := scalekitClient.Organization().CreateDomain(ctx, organizationID, scalekit.CreateDomainOptions{ 18 Domain: "acmecorp.com", 19 DomainType: "ORGANIZATION_DOMAIN", 20 }) 21 // newDomain.TxtRecordKey and newDomain.TxtRecordSecret contain the DNS record values 22 23 // 2. List all organization domains 24 domains, err := scalekitClient.Organization().ListDomains(ctx, organizationID, scalekit.ListDomainsOptions{ 25 DomainType: "ORGANIZATION_DOMAIN", 26 }) 27 28 // 3. Get a specific domain 29 domain, err := scalekitClient.Organization().GetDomain(ctx, organizationID, domainID) 30 31 // 4. Delete a domain 32 err = scalekitClient.Organization().DeleteDomain(ctx, organizationID, domainID) ``` * Java Manage organization domains ```java 1 import com.scalekit.client.Scalekit; 2 3 Scalekit scalekitClient = new Scalekit( 4 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 5 System.getenv("SCALEKIT_CLIENT_ID"), 6 System.getenv("SCALEKIT_CLIENT_SECRET") 7 ); 8 9 // 1. Add an organization domain 10 Domain newDomain = scalekitClient.organizations() 11 .createDomain(organizationId, new CreateDomainOptions() 12 .setDomain("acmecorp.com") 13 .setDomainType("ORGANIZATION_DOMAIN")); 14 // newDomain.getTxtRecordKey() and newDomain.getTxtRecordSecret() contain the DNS record values 15 16 // 2. List all organization domains 17 List domains = scalekitClient.organizations() 18 .listDomains(organizationId, new ListDomainsOptions() 19 .setDomainType("ORGANIZATION_DOMAIN")); 20 21 // 3. Get a specific domain 22 Domain domain = scalekitClient.organizations().getDomain(organizationId, domainId); 23 24 // 4. Delete a domain 25 scalekitClient.organizations().deleteDomain(organizationId, domainId); ``` ## Listen for organization domain events [Section titled “Listen for organization domain events”](#listen-for-organization-domain-events) Subscribe to these webhook events to react to domain lifecycle changes in your application: | Event | Fires when | | ---------------------------------------------- | ------------------------------------------------------------------ | | `organization.domain_created` | A domain is added to an organization via any method | | `organization.domain_deleted` | A domain is removed from an organization | | `organization.domain_dns_verification_success` | The DNS check confirms domain ownership | | `organization.domain_dns_verification_failed` | The DNS verification window expired without a successful DNS match | All four events share the same `data` shape: organization.domain\_created ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_4567890123", 4 "object": "Organization", 5 "occurred_at": "2024-01-15T11:00:00.123456789Z", 6 "organization_id": "org_1234567890", 7 "spec_version": "1", 8 "type": "organization.domain_created", 9 "data": { 10 "id": "dom_1234567890", 11 "domain": "acmecorp.com", 12 "domain_type": "ORGANIZATION_DOMAIN", 13 "organization_id": "org_1234567890", 14 "environment_id": "env_1234567890", 15 "txt_record_key": "scalekit-domain-verification", 16 "txt_record_secret": "sk_dom_verify_abc123", 17 "verification_status": "PENDING", 18 "verification_method": "DNS", 19 "updated_at": "2024-01-15T11:00:00.123456789Z" 20 } 21 } ``` | Field | Type | Description | | --------------------- | ------ | ---------------------------------------------------------------------------------------------------- | | `id` | string | Unique identifier for the domain (`dom_` prefix) | | `domain` | string | The domain name | | `domain_type` | string | `ORGANIZATION_DOMAIN` for SSO/SCIM domains; `ALLOWED_EMAIL_DOMAIN` for auto-join domains | | `organization_id` | string | Organization that owns the domain (`org_` prefix) | | `environment_id` | string | Environment where the domain is configured (`env_` prefix) | | `txt_record_key` | string | DNS TXT record host used for ownership verification | | `txt_record_secret` | string | DNS TXT value Scalekit expects. Treat as sensitive — do not log or expose in client UIs | | `verification_status` | string | `PENDING`, `VERIFIED`, `FAILED`, or `AUTO_VERIFIED` | | `verification_method` | string | `DNS` (TXT record), `ADMIN` (added by the B2B app team), or `NOT_APPLICABLE` (allowed email domains) | | `updated_at` | string | When the domain status last changed | Configure handlers with the [webhooks guide](/authenticate/implement-workflows/implement-webhooks/). ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) --- # DOCUMENT BOUNDARY --- # Implement organization switcher > Let users switch across workspaces using prompt-based selection or direct org routing via organization ID Organization switching lets users access multiple organizations or workspaces within your application. This guide shows you how to implement organization switching using Scalekit’s built-in switcher or by building your own organization switcher in your application. This feature is essential for B2B applications where users may belong to several organizations simultaneously. Common scenarios include: * **Personal workspace to corporate workspace**: Users sign up with their organization’s email address, creating their personal workspace. Later, when their organization subscribes to your app, a new corporate workspace is created (for example, “AcmeCorp workspace”). * **Multi-organization contractors**: External consultants or contractors who belong to multiple organizations, each with their own SSO authentication policies. These users need to switch between different client organizations while maintaining secure access to each workspace. ![Scalekit organization switcher screen listing a user's organizations and a pending invitation with a Join button](/.netlify/images?url=_astro%2F1-switcher.BmXDeGKX.png\&w=2940\&h=1662\&dpl=6aaa70ad2ea7b40008ad2afd) ## Default organization switching behavior [Section titled “Default organization switching behavior”](#default-organization-switching-behavior) When users belong to multiple organizations, Scalekit automatically handles organization switching during the authentication flow: 1. Users click **Sign In** on your application. 2. Your application redirects users to Scalekit’s sign-in page. 3. Users authenticate using one of the available sign-in methods. 4. Scalekit displays a list of organizations that users belong to. 5. Users select the organization they want to sign in to. 6. Users are redirected to the organization’s workspace and signed in. Scalekit provides built-in support for organization switching through automatic organization detection, a hosted organization switcher UI, and secure session management. Each organization maintains its own authentication context and policies. ## Control organization switching behavior [Section titled “Control organization switching behavior”](#control-organization-switching-behavior) You can customize the organization switcher’s behavior by adding query parameters when generating the authorization URL. These parameters give you precise control over how users navigate between organizations. ### Display organization switcher [Section titled “Display organization switcher”](#display-organization-switcher) Add the `prompt: 'select_account'` parameter when generating the authorization URL. This forces Scalekit to display a list of organizations the user belongs to, even if they’re already signed in. * Node.js Express.js ```diff 1 // Use case: Show organization switcher after user authentication 2 const redirectUri = 'http://localhost:3000/api/callback'; 3 const options = { 4 scopes: ['openid', 'profile', 'email', 'offline_access'], 5 prompt: 'select_account' 6 }; 7 8 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); 9 10 res.redirect(authorizationUrl); ``` * Python Flask ```diff 1 # Use case: Show organization switcher after user authentication 2 from scalekit import AuthorizationUrlOptions 3 4 redirect_uri = 'http://localhost:3000/api/callback' 5 options = AuthorizationUrlOptions() 6 options.scopes = ['openid', 'profile', 'email', 'offline_access'] 7 options.prompt = 'select_account' 8 9 authorization_url = scalekit.get_authorization_url(redirect_uri, options) 10 return redirect(authorization_url) ``` * Go Gin ```diff 1 // Use case: Show organization switcher after user authentication 2 redirectUri := "http://localhost:3000/api/callback" 3 options := scalekit.AuthorizationUrlOptions{ 4 Scopes: []string{"openid", "profile", "email", "offline_access"}, 5 +Prompt: "select_account", 6 } 7 8 authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options) 9 if err != nil { 10 // handle error appropriately 11 panic(err) 12 } 13 14 c.Redirect(http.StatusFound, authorizationUrl.String()) ``` * Java Spring ```diff 1 // Use case: Show organization switcher after user authentication 2 import com.scalekit.internal.http.AuthorizationUrlOptions; 3 import java.net.URL; 4 import java.util.Arrays; 5 6 String redirectUri = "http://localhost:3000/api/callback"; 7 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 8 +options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access")); 9 options.setPrompt("select_account"); 10 11 URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options); ``` This displays the organization switcher UI where users can choose which organization to access. ### Switch users directly to a specific organization [Section titled “Switch users directly to a specific organization”](#switch-users-directly-to-a-specific-organization) To bypass the organization switcher and directly authenticate users into a specific organization, include both the `prompt: 'select_account'` parameter and the `organizationId` parameter: * Node.js Express.js ```diff 1 // Use case: Directly route users to a specific organization 2 const redirectUri = 'http://localhost:3000/api/callback'; 3 const options = { 4 scopes: ['openid', 'profile', 'email', 'offline_access'], 5 prompt: 'select_account', 6 organizationId: 'org_1233434' 7 }; 8 9 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); 10 11 res.redirect(authorizationUrl); ``` * Python Flask ```diff 1 # Use case: Directly route users to a specific organization 2 from scalekit import AuthorizationUrlOptions 3 4 redirect_uri = 'http://localhost:3000/api/callback' 5 options = AuthorizationUrlOptions() 6 options.scopes = ['openid', 'profile', 'email', 'offline_access'] 7 options.prompt = 'select_account' 8 options.organization_id = 'org_1233434' 9 10 authorization_url = scalekit.get_authorization_url(redirect_uri, options) 11 return redirect(authorization_url) ``` * Go Gin ```diff 1 // Use case: Directly route users to a specific organization 2 redirectUri := "http://localhost:3000/api/callback" 3 options := scalekit.AuthorizationUrlOptions{ 4 +Scopes: []string{"openid", "profile", "email", "offline_access"}, 5 +Prompt: "select_account", 6 OrganizationId: "org_1233434", 7 } 8 9 authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options) 10 if err != nil { 11 // handle error appropriately 12 panic(err) 13 } 14 15 c.Redirect(http.StatusFound, authorizationUrl.String()) ``` * Java Spring ```diff 1 // Use case: Directly route users to a specific organization 2 import com.scalekit.internal.http.AuthorizationUrlOptions; 3 import java.net.URL; 4 import java.util.Arrays; 5 6 String redirectUri = "http://localhost:3000/api/callback"; 7 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 8 +options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access")); 9 +options.setPrompt("select_account"); 10 options.setOrganizationId("org_1233434"); 11 12 URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options); ``` When you include both parameters, Scalekit will: * **If the user is already authenticated**: Directly sign them into the specified organization * **If the user needs to authenticate**: First authenticate the user, then sign them into the specified organization ## Organization switching parameters [Section titled “Organization switching parameters”](#organization-switching-parameters) Use these parameters to control the organization switching behavior: | Parameter | Description | Example | | ---------------------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- | | `prompt=select_account` | Shows the organization switcher UI | Forces organization selection even for authenticated users | | `prompt=select_account&organizationId=org_123` | Direct organization access | Bypasses switcher and authenticates directly into the specified organization | --- # DOCUMENT BOUNDARY --- # Provision users and groups with SCIM > Automate user and group lifecycle management using SCIM provisioning Scalekit supports user and group provisioning using the [SCIM protocol](/directory/guides/user-provisioning-basics/), allowing your customers to manage access to their organization in your app directly from their directory provider. With SCIM, the directory becomes the source of truth for organization membership, user profile attributes, and access — eliminating manual invites, role drift, and delayed deprovisioning. SCIM ensures that access to your application always reflects the organization’s directory state, from onboarding to offboarding. Using SCIM, your customers can: * Add users to their organization * Keep user attributes (like name, email or role) in sync * Remove users from their organization * Control application roles through directory group membership SCIM provisioning enables end-to-end lifecycle management, ensuring access is granted, updated, and revoked automatically as users move through the organization. *** ### Who should use SCIM provisioning? [Section titled “Who should use SCIM provisioning?”](#who-should-use-scim-provisioning) SCIM provisioning is recommended for: * Enterprise customers that require **centralized identity management** * Teams already using a directory provider like Okta, Azure AD (Entra ID), or Google Workspace * Customers that need **group-based access control** and automated deprovisioning *** ### Manage SCIM provisioning [Section titled “Manage SCIM provisioning”](#manage-scim-provisioning) 1. ## Register organization-owned domains [Section titled “Register organization-owned domains”](#register-organization-owned-domains) Register the email domains owned by the organization. SCIM provisioning only works for users whose email domain matches one of the organization’s registered [Organization domains](/authenticate/manage-users-orgs/organization-domains/). This ensures that only verified members of the organization can be automatically provisioned. **Contractors and external users** with non-matching domains (e.g., `joe@ext.yourapp.com`) cannot be automatically provisioned via SCIM. These users must be [manually invited](/fsa/guides/user-invitations/) to join the organization. This ensures that unauthorized users cannot obtain access automatically. Navigate to **Dashboard** > **Organizations** and select the target organization > **Overview** > **Organization Domains** section to register organization domains. 2. ## Enable SCIM provisioning for the organization [Section titled “Enable SCIM provisioning for the organization”](#enable-scim-provisioning-for-the-organization) SCIM provisioning should be enabled for the target organization either through the Scalekit Dashboard or the self-service [Admin Portal](/guides/admin-portal/). Follow the detailed setup instructions [here](/guides/user-management/scim-provisioning/). 3. ## Provision users and groups from the directory [Section titled “Provision users and groups from the directory”](#provision-users-and-groups-from-the-directory) Once SCIM provisioning is enabled for the organization, the directory becomes the system of record for that organization in your app. Organization administrators can manage access directly from their IdP by: * Assigning users or groups to your application * Updating user profile attributes * Removing users or groups to revoke access 4. ## Group-based role assignment [Section titled “Group-based role assignment”](#group-based-role-assignment) Scalekit supports assigning roles to users in your app based on directory group membership. This enables consistent, policy-driven access control managed entirely from the directory provider. * Map directory groups to application roles in Scalekit * Users receive roles automatically when added to mapped groups * Roles are revoked when users are removed from those groups, including when the group itself is deleted in the directory * If a user belongs to multiple mapped groups, deleting one group recalculates the user’s role from their remaining group memberships instead of leaving the deleted group’s role in place 5. ## User attribute mapping [Section titled “User attribute mapping”](#user-attribute-mapping) Scalekit automatically maps the following user attributes from the directory to the Scalekit user profile: * `email` * `preferred_username` * `name` * `given_name` * `family_name` * `picture` * `phone_number` * `locale` * `custom_attributes` When attributes change in the directory, Scalekit updates the user profile automatically during SCIM synchronization. *** ### Supported directory providers [Section titled “Supported directory providers”](#supported-directory-providers) Scalekit supports SCIM provisioning with common enterprise directory providers including Okta, Entra ID (Azure AD), and Google Workspace. See the full list of supported providers [here](/guides/integrations/scim-integrations/). *** ### Common SCIM provisioning scenarios [Section titled “Common SCIM provisioning scenarios”](#common-scim-provisioning-scenarios) --- # DOCUMENT BOUNDARY --- # MCP Servers - Additional Reading > Explore advanced topics for MCP servers, including OAuth 2.1 flows, scope design, dynamic client registration, and security best practices. MCP Clients that want to get authorized to access your MCP Server need to follow either of the below OAuth 2.1 Flows Supported by Scalekit. ## OAuth 2.1 Flows Supported [Section titled “OAuth 2.1 Flows Supported”](#oauth-21-flows-supported) ### Authorization Code Flow [Section titled “Authorization Code Flow”](#authorization-code-flow) Ideal when an AI agent or MCP Client acts on behalf of a human user: ```javascript 1 // Step 1: Redirect user to authorization server 2 const authURL = new URL('https://your-org.scalekit.com/oauth/authorize'); 3 authURL.searchParams.set('response_type', 'code'); 4 authURL.searchParams.set('client_id', 'your-client-id'); 5 authURL.searchParams.set('redirect_uri', 'https://your-app.com/callback'); 6 authURL.searchParams.set('scope', 'mcp:tools:calendar:read mcp:tools:email:send'); 7 authURL.searchParams.set('state', generateSecureRandomString()); 8 authURL.searchParams.set('code_challenge', generatePKCEChallenge()); 9 authURL.searchParams.set('code_challenge_method', 'S256'); 10 11 // Step 2: Handle callback and exchange code for token 12 app.get('/callback', async (req, res) => { 13 const { code, state } = req.query; 14 15 // Verify state parameter to prevent CSRF 16 if (!isValidState(state)) { 17 return res.status(400).json({ error: 'Invalid state parameter' }); 18 } 19 20 const tokenResponse = await fetch('https://your-org.scalekit.com/oauth/token', { 21 method: 'POST', 22 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 23 body: new URLSearchParams({ 24 grant_type: 'authorization_code', 25 code, 26 client_id: 'your-client-id', 27 redirect_uri: 'https://your-app.com/callback', 28 code_verifier: getPKCEVerifier() // From PKCE challenge generation 29 }) 30 }); 31 32 const tokens = await tokenResponse.json(); 33 // Store tokens securely and proceed with MCP calls 34 }); ``` ### Client Credentials Flow [Section titled “Client Credentials Flow”](#client-credentials-flow) Perfect for automated agents that don’t represent a specific user but want to access your MCP Server on their own behalf. This is typically used for Machine-to-Machine (M2M) authentication. ```javascript 1 const getMachineToken = async () => { 2 const response = await fetch('https://your-org.scalekit.com/oauth/token', { 3 method: 'POST', 4 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 5 body: new URLSearchParams({ 6 grant_type: 'client_credentials', 7 client_id: 'your-service-client-id', 8 client_secret: 'your-service-client-secret', 9 scope: 'mcp:tools:inventory:check mcp:resources:store-data', 10 audience: 'https://your-mcp-server.com', 11 }) 12 }); 13 14 return await response.json(); 15 }; ``` ## Scope Design Best Practices [Section titled “Scope Design Best Practices”](#scope-design-best-practices) Design OAuth scopes that reflect your MCP server’s actual capabilities and security requirements: ### Hierarchical Scopes [Section titled “Hierarchical Scopes”](#hierarchical-scopes) ```javascript 1 // Resource-based scopes 2 'mcp:resources:customer-data:read' // Read customer data 3 'mcp:resources:customer-data:write' // Modify customer data 4 'mcp:resources:*' // All resources (admin-level) 5 6 // Tool-based scopes 7 'mcp:tools:weather' // Weather API access 8 'mcp:tools:calendar:read' // Read calendar events 9 'mcp:tools:calendar:write' // Create/modify calendar events 10 'mcp:tools:email:send' // Send emails 11 'mcp:tools:*' // All tools access 12 13 // Action-based scopes 14 'mcp:exec:workflows:risk-assessment' // Execute risk assessment workflow 15 'mcp:exec:functions:data-analysis' // Run data analysis functions ``` ### Scope Validation Helpers [Section titled “Scope Validation Helpers”](#scope-validation-helpers) ```javascript 1 const ScopeValidator = { 2 hasScope: (userScopes, requiredScope) => { 3 return userScopes.includes(requiredScope) || 4 userScopes.includes(requiredScope.split(':').slice(0, -1).join(':') + ':*'); 5 }, 6 7 hasAnyScope: (userScopes, allowedScopes) => { 8 return allowedScopes.some(scope => ScopeValidator.hasScope(userScopes, scope)); 9 }, 10 11 validateToolAccess: (userScopes, toolName) => { 12 const toolScope = `mcp:tools:${toolName}`; 13 const wildcardScope = 'mcp:tools:*'; 14 return userScopes.includes(toolScope) || userScopes.includes(wildcardScope); 15 } 16 }; 17 18 // Usage in MCP tool handlers 19 app.post('/mcp/tools/:toolName', (req, res) => { 20 const { toolName } = req.params; 21 const userScopes = req.auth.scopes; 22 23 if (!ScopeValidator.validateToolAccess(userScopes, toolName)) { 24 return res.status(403).json({ 25 error: 'insufficient_scope', 26 error_description: `Access to tool '${toolName}' requires appropriate scope` 27 }); 28 } 29 30 // Process tool request 31 }); ``` ## Dynamic Client Registration [Section titled “Dynamic Client Registration”](#dynamic-client-registration) Scalekit supports Dynamic Client Registration (DCR) to enable seamless integration for new MCP clients that want to connect to your MCP Server. MCP clients can auto-register using DCR: ```javascript 1 // MCP clients can auto-register using DCR 2 const registerClient = async (clientMetadata) => { 3 const response = await fetch('https://your-org.scalekit.com/resource-server/oauth/register', { 4 method: 'POST', 5 headers: { 'Content-Type': 'application/json' }, 6 body: JSON.stringify({ 7 client_name: 'AI Sales Assistant', 8 client_uri: 'https://sales-ai.company.com', 9 redirect_uris: ['https://sales-ai.company.com/oauth/callback'], 10 grant_types: ['authorization_code', 'refresh_token'], 11 response_types: ['code'], 12 scope: 'mcp:tools:crm:read mcp:tools:email:send', 13 audience: 'https://your-mcp-server.com', 14 token_endpoint_auth_method: 'client_secret_basic', 15 ...clientMetadata 16 }) 17 }); 18 19 return await response.json(); 20 // Returns: { client_id, client_secret, client_id_issued_at, ... } 21 }; ``` ## Security Implementation [Section titled “Security Implementation”](#security-implementation) ### Rate Limiting by Client [Section titled “Rate Limiting by Client”](#rate-limiting-by-client) Implement client-specific rate limits: ```javascript 1 import rateLimit from 'express-rate-limit'; 2 3 const createClientRateLimit = () => { 4 return rateLimit({ 5 windowMs: 15 * 60 * 1000, // 15 minutes 6 limit: (req) => { 7 // Different limits based on client type or scopes 8 const scopes = req.auth?.scopes || []; 9 if (scopes.includes('mcp:tools:*')) return 1000; // Premium client 10 if (scopes.includes('mcp:tools:basic')) return 100; // Basic client 11 return 50; // Default limit 12 }, 13 keyGenerator: (req) => req.auth?.clientId || req.ip, 14 message: { 15 error: 'rate_limit_exceeded', 16 error_description: 'Too many requests from this client' 17 } 18 }); 19 }; 20 21 app.use('/mcp', createClientRateLimit()); ``` ### Comprehensive Logging [Section titled “Comprehensive Logging”](#comprehensive-logging) Track all OAuth and MCP interactions: ```javascript 1 const auditLogger = { 2 logTokenRequest: (clientId, grantType, scopes, success) => { 3 console.log(JSON.stringify({ 4 event: 'oauth_token_request', 5 timestamp: new Date().toISOString(), 6 client_id: clientId, 7 grant_type: grantType, 8 requested_scopes: scopes, 9 success 10 })); 11 }, 12 13 logMCPAccess: (req, toolName, success, error = null) => { 14 console.log(JSON.stringify({ 15 event: 'mcp_tool_access', 16 timestamp: new Date().toISOString(), 17 user_id: req.auth?.userId, 18 client_id: req.auth?.clientId, 19 tool_name: toolName, 20 scopes: req.auth?.scopes, 21 success, 22 error: error?.message, 23 ip_address: req.ip, 24 user_agent: req.get('User-Agent') 25 })); 26 } 27 }; 28 29 // Use in your MCP handlers 30 app.post('/mcp/tools/:toolName', async (req, res) => { 31 const { toolName } = req.params; 32 33 try { 34 // Process tool request 35 const result = await processToolRequest(toolName, req.body); 36 37 auditLogger.logMCPAccess(req, toolName, true); 38 res.json(result); 39 } catch (error) { 40 auditLogger.logMCPAccess(req, toolName, false, error); 41 res.status(500).json({ error: 'Tool execution failed' }); 42 } 43 }); ``` ### Health Check Endpoints [Section titled “Health Check Endpoints”](#health-check-endpoints) Monitor your MCP server and authorization integration: ```javascript 1 app.get('/health', async (req, res) => { 2 const health = { 3 status: 'healthy', 4 timestamp: new Date().toISOString(), 5 services: { 6 mcp_server: 'healthy', 7 oauth_server: 'unknown' 8 } 9 }; 10 11 try { 12 // Test OAuth server connectivity 13 const oauthTest = await fetch('https://your-org.scalekit.com/.well-known/oauth-authorization-server'); 14 health.services.oauth_server = oauthTest.ok ? 'healthy' : 'degraded'; 15 } catch (error) { 16 health.services.oauth_server = 'unhealthy'; 17 health.status = 'degraded'; 18 } 19 20 const statusCode = health.status === 'healthy' ? 200 : 503; 21 res.status(statusCode).json(health); 22 }); ``` ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) ### Common Issues and Solutions [Section titled “Common Issues and Solutions”](#common-issues-and-solutions) **Token Validation Failures** ```javascript 1 // Debug token validation issues 2 const debugTokenValidation = async (token) => { 3 try { 4 // Check token structure 5 const [header, payload, signature] = token.split('.'); 6 console.log('Token Header:', JSON.parse(atob(header))); 7 console.log('Token Payload:', JSON.parse(atob(payload))); 8 9 // Validate with detailed error info 10 await jwtVerify(token, JWKS, { 11 issuer: 'https://your-org.scalekit.com', 12 audience: 'https://your-mcp-server.com' 13 }); 14 } catch (error) { 15 console.error('Token validation error:', { 16 name: error.name, 17 message: error.message, 18 code: error.code 19 }); 20 } 21 }; ``` **CORS Issues with Authorization Server** ```javascript 1 // Configure CORS for OAuth endpoints 2 app.use('/oauth', cors({ 3 origin: 'https://your-org.scalekit.com', 4 credentials: true, 5 methods: ['GET', 'POST', 'OPTIONS'], 6 allowedHeaders: ['Authorization', 'Content-Type', 'MCP-Protocol-Version'] 7 })); ``` **Scope Permission Debugging** ```javascript 1 const debugScopes = (req, res, next) => { 2 console.log('Request Scopes:', { 3 user_scopes: req.auth?.scopes, 4 required_scope: req.requiredScope, 5 has_permission: req.auth?.scopes?.includes(req.requiredScope) 6 }); 7 next(); 8 }; ``` ### Error Response Standards [Section titled “Error Response Standards”](#error-response-standards) Follow OAuth 2.1 and MCP error response formats: ```javascript 1 const sendOAuthError = (res, error, description, statusCode = 400) => { 2 res.status(statusCode).json({ 3 error, 4 error_description: description, 5 error_uri: 'https://your-mcp-server.com/docs/errors' 6 }); 7 }; 8 9 // Usage examples 10 app.use((error, req, res, next) => { 11 if (error.name === 'TokenExpiredError') { 12 return sendOAuthError(res, 'invalid_token', 'Access token has expired', 401); 13 } 14 15 if (error.name === 'InsufficientScopeError') { 16 return sendOAuthError(res, 'insufficient_scope', `Required scope: ${error.requiredScope}`, 403); 17 } 18 19 // Default error 20 sendOAuthError(res, 'server_error', 'An unexpected error occurred', 500); 21 }); ``` ## Advanced Configuration [Section titled “Advanced Configuration”](#advanced-configuration) ### Custom Scope Mapping [Section titled “Custom Scope Mapping”](#custom-scope-mapping) Map OAuth scopes to internal permissions: ```javascript 1 const scopePermissionMap = { 2 'mcp:tools:weather': ['weather:read'], 3 'mcp:tools:calendar:read': ['calendar:events:read'], 4 'mcp:tools:calendar:write': ['calendar:events:read', 'calendar:events:write'], 5 'mcp:tools:email:send': ['email:send', 'contacts:read'], 6 'mcp:resources:customer-data': ['customers:read', 'customers:write'] 7 }; 8 9 const getPermissionsFromScopes = (scopes) => { 10 const permissions = new Set(); 11 scopes.forEach(scope => { 12 const scopePermissions = scopePermissionMap[scope] || []; 13 scopePermissions.forEach(permission => permissions.add(permission)); 14 }); 15 return Array.from(permissions); 16 }; ``` ### Refresh Token Management [Section titled “Refresh Token Management”](#refresh-token-management) Handle token refresh for long-running agents: ```javascript 1 const TokenManager = { 2 async refreshToken(refreshToken) { 3 const response = await fetch('https://your-org.scalekit.com/oauth2/token', { 4 method: 'POST', 5 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 6 body: new URLSearchParams({ 7 grant_type: 'refresh_token', 8 refresh_token: refreshToken, 9 client_id: 'your-client-id', 10 client_secret: 'your-client-secret' 11 }) 12 }); 13 14 return await response.json(); 15 }, 16 17 async autoRefreshWrapper(tokenStore, makeRequest) { 18 try { 19 return await makeRequest(tokenStore.accessToken); 20 } catch (error) { 21 if (error.status === 401) { 22 // Token expired, try refresh 23 const newTokens = await this.refreshToken(tokenStore.refreshToken); 24 tokenStore.accessToken = newTokens.access_token; 25 tokenStore.refreshToken = newTokens.refresh_token; 26 27 // Retry original request 28 return await makeRequest(tokenStore.accessToken); 29 } 30 throw error; 31 } 32 } 33 }; ``` --- # DOCUMENT BOUNDARY --- # MCP authentication patterns > Authentication patterns: Human users via OAuth Authorization Code flow, autonomous agents via Client Credentials flow, and downstream integrations using API keys, OAuth, or token cascading Scalekit provides secure authentication for MCP servers across three distinct patterns, each corresponding to different interaction models and trust boundaries. Understanding which pattern applies to your use case ensures you implement the right security model for your MCP server architecture. This guide covers all three authentication patterns: human-to-MCP interactions, agent-to-MCP communication, and MCP-to-downstream integrations. Each pattern uses different OAuth 2.1 flows and has specific configuration requirements explained with sequence diagrams and practical guidance. ## Pattern comparison [Section titled “Pattern comparison”](#pattern-comparison) Understanding the differences between these patterns helps you choose the right approach for your architecture. Each pattern serves specific use cases and has different security characteristics. | Aspect | Human → MCP | Agent/Machine → MCP | MCP → Downstream | | -------------------- | ---------------------------------------------- | -------------------------------------- | -------------------------------------- | | **Actor** | Human using AI host (Claude, ChatGPT, VS Code) | Autonomous agent or service | MCP Server making backend calls | | **OAuth Flow** | Authorization Code | Client Credentials | Varies by sub-pattern | | **Initiator** | User interaction in MCP client | Programmatic request | MCP server implementation code | | **Token Lifetime** | Medium (typically hours) | Configurable (typically long-lived) | Depends on downstream system | | **User Consent** | Required during authorization flow | Not applicable (pre-configured) | Not applicable | | **Scope Assignment** | During consent prompt | At client registration | At implementation time | | **Best For** | Interactive human workflows | Scheduled tasks, autonomous operations | Backend integration with APIs/services | | **Complexity** | Medium (handles browser flow) | Low (direct token request) | Varies (simple to complex) | ## Pattern 1: Human interacting with MCP server [Section titled “Pattern 1: Human interacting with MCP server”](#pattern-1-human-interacting-with-mcp-server) When a human uses a compliant MCP host application, that host acts as the OAuth client. It initiates authorization with the Scalekit Authorization Server, obtains a scoped access token, and interacts securely with the MCP Server on behalf of the user. This pattern represents the most common interaction model for real-world MCP use cases - humans interacting with an MCP server through AI host applications like Claude Desktop, VS Code, Cursor, or Windsurf, while Scalekit ensures tokens are valid, scoped, and auditable. ### Authorization sequence [Section titled “Authorization sequence”](#authorization-sequence) ### How it works [Section titled “How it works”](#how-it-works) 1. **Initiation** – The human configures an MCP server in their MCP client application. 2. **Challenge** – The MCP Server responds with an HTTP `401` containing a `WWW-Authenticate` header that points to the Scalekit Authorization Server. 3. **Authorization Flow** – The MCP Client opens the user’s browser to initiate the OAuth 2.1 authorization flow. During this step, the Scalekit Authorization Server handles user authentication through Magic Link & OTP, Passkeys, Social login providers (like Google, GitHub, or LinkedIn), or Enterprise SSO integrations (such as Okta, Microsoft Entra ID, or ADFS). The user is then prompted to grant consent for the requested scopes. Once approved, Scalekit returns an authorization code, which the MCP Client exchanges for an access token. 4. **Token Issuance** – Scalekit issues an OAuth 2.1 access token containing claims and scopes (for example, `todo:read`, `calendar:write`) that represent the user’s permissions. 5. **Authorized Request** – The client calls the MCP Server again, now attaching the Bearer token in the `Authorization` header. 6. **Validation and Execution** – The MCP Server validates the token issued by Scalekit and executes the requested tool. ### Implementation [Section titled “Implementation”](#implementation) #### 1. Register your MCP server in the Scalekit Dashboard [Section titled “1. Register your MCP server in the Scalekit Dashboard”](#1-register-your-mcp-server-in-the-scalekit-dashboard) Create a new MCP server in the Scalekit Dashboard to obtain your server credentials and configure authentication settings. #### 2. Implement the protected resource metadata endpoint [Section titled “2. Implement the protected resource metadata endpoint”](#2-implement-the-protected-resource-metadata-endpoint) Add a `.well-known/oauth-protected-resource` endpoint that provides your MCP server’s authentication configuration to clients. #### 3. Configure scopes for your server capabilities [Section titled “3. Configure scopes for your server capabilities”](#3-configure-scopes-for-your-server-capabilities) Define OAuth scopes that correspond to the tools and permissions your MCP server exposes. #### 4. Set up token validation middleware [Section titled “4. Set up token validation middleware”](#4-set-up-token-validation-middleware) Implement middleware to validate incoming JWT tokens from Scalekit before processing MCP tool requests. #### 5. Test the complete authentication flow [Section titled “5. Test the complete authentication flow”](#5-test-the-complete-authentication-flow) Verify the end-to-end flow works with an MCP client to ensure secure authentication. For complete implementation guidance, see the [MCP OAuth 2.1 quickstart](/authenticate/mcp/quickstart/) or framework-specific guides for [FastMCP](/authenticate/mcp/fastmcp-quickstart/), [FastAPI + FastMCP](/authenticate/mcp/fastapi-fastmcp-quickstart/), and [Express.js](/authenticate/mcp/expressjs-quickstart/). ## Pattern 2: Agent / machine interacting with MCP server [Section titled “Pattern 2: Agent / machine interacting with MCP server”](#pattern-2-agent--machine-interacting-with-mcp-server) An autonomous agent or any machine-to-machine process can directly interact with an MCP Server secured by Scalekit. In this model, the agent acts as a confidential OAuth client, authenticated using a `client_id` and `client_secret` issued by Scalekit. This pattern uses the OAuth 2.1 Client Credentials flow, allowing the agent to obtain an access token without user interaction. Tokens are scoped and time-bound, ensuring secure and auditable automation between services. ### Authorization sequence [Section titled “Authorization sequence”](#authorization-sequence-1) ### Client registration [Section titled “Client registration”](#client-registration) #### 1. Navigate to the MCP Server Clients tab [Section titled “1. Navigate to the MCP Server Clients tab”](#1-navigate-to-the-mcp-server-clients-tab) Go to **[Dashboard](https://app.scalekit.com) > MCP Servers** and select your MCP Server. Click on the **Clients** tab. ![Clients tab](/.netlify/images?url=_astro%2Fmcp-client-nav.C6UPUhIu.png\&w=1148\&h=1242\&dpl=6aaa70ad2ea7b40008ad2afd) #### 2. Create a new M2M client [Section titled “2. Create a new M2M client”](#2-create-a-new-m2m-client) Click **Create Client** to start the client creation process. ![Create client](/.netlify/images?url=_astro%2Fmcp-clients-tab.UgPaVUGm.png\&w=3020\&h=1040\&dpl=6aaa70ad2ea7b40008ad2afd) #### 3. Copy your client credentials [Section titled “3. Copy your client credentials”](#3-copy-your-client-credentials) Copy the **client\_id** and **client\_secret** immediately - the secret will not be shown again for security reasons. Store these securely in your agent’s configuration. ![Client credentials](/.netlify/images?url=_astro%2Fmcp-client-sidesheet.D9KN4b5q.png\&w=3020\&h=1500\&dpl=6aaa70ad2ea7b40008ad2afd) #### 4. Configure client scopes [Section titled “4. Configure client scopes”](#4-configure-client-scopes) Optionally, set scopes (e.g., `todo:read`, `todo:write`) that correspond to the permissions configured for your MCP Server. Click **Save** to complete the setup. ### Requesting an access token [Section titled “Requesting an access token”](#requesting-an-access-token) Once you have the client credentials, the agent can request a token directly from the Scalekit Authorization Server: Request access token ```bash 1 curl --location '{{env_url}}/oauth/token' \ 2 --header 'Content-Type: application/x-www-form-urlencoded' \ 3 --data-urlencode 'grant_type=client_credentials' \ 4 --data-urlencode 'client_id={{client_id}}' \ 5 --data-urlencode 'client_secret={{secret_value}}' \ 6 --data-urlencode 'scope=todo:read todo:write' ``` Scalekit responds with a JSON payload containing the access token: Token response ```json { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIn0...", "token_type": "Bearer", "expires_in": 3600, "scope": "todo:read todo:write" } ``` Use the `access_token` in the `Authorization` header when calling your MCP Server’s endpoints. ### Implementation [Section titled “Implementation”](#implementation-1) #### 1. Create an M2M client for your target MCP server [Section titled “1. Create an M2M client for your target MCP server”](#1-create-an-m2m-client-for-your-target-mcp-server) Use the Scalekit Dashboard to create a Machine-to-Machine client for the MCP server you want to authenticate with. #### 2. Store client credentials securely [Section titled “2. Store client credentials securely”](#2-store-client-credentials-securely) Store the `client_id` and `client_secret` using environment variables or a secrets manager. Never hardcode credentials in your agent code. #### 3. Implement token requests in your agent [Section titled “3. Implement token requests in your agent”](#3-implement-token-requests-in-your-agent) Before making MCP calls, request access tokens using the OAuth 2.1 Client Credentials flow from the Scalekit Authorization Server. #### 4. Add token caching and refresh logic [Section titled “4. Add token caching and refresh logic”](#4-add-token-caching-and-refresh-logic) Implement caching to store tokens until they expire, and refresh them automatically to maintain uninterrupted service. #### 5. Attach tokens to MCP tool requests [Section titled “5. Attach tokens to MCP tool requests”](#5-attach-tokens-to-mcp-tool-requests) Include the access token as a Bearer token in the `Authorization` header when calling MCP server tools. For hands-on experience, use the FastMCP Todo Server from the [FastMCP quickstart](/authenticate/mcp/fastmcp-quickstart/). Create an M2M client and run your token request programmatically within your agent code. ## Pattern 3: MCP server integrating with downstream systems [Section titled “Pattern 3: MCP server integrating with downstream systems”](#pattern-3-mcp-server-integrating-with-downstream-systems) In real-world scenarios, an MCP Server often needs to make backend calls - to your own APIs, to another MCP Server, or to external APIs such as CRM, ticketing, or SaaS tools. This section explains three secure ways to perform these downstream integrations, each corresponding to a different trust boundary and authorization pattern. ### Sub-pattern 3a: Using API keys or custom tokens [Section titled “Sub-pattern 3a: Using API keys or custom tokens”](#sub-pattern-3a-using-api-keys-or-custom-tokens) Your MCP Server can communicate with internal or external backend systems that have their own authorization servers or API key-based access. In this setup, the MCP Server manages its own credentials securely (for example, in environment variables, a vault, or secrets manager) and injects them when making downstream calls. #### Authorization sequence [Section titled “Authorization sequence”](#authorization-sequence-2) #### When to use this pattern [Section titled “When to use this pattern”](#when-to-use-this-pattern) * External APIs have their own authentication (AWS, Stripe, Twilio, etc.) * Internal systems use proprietary authentication mechanisms * Legacy systems that don’t support OAuth 2.1 * You control credential management and rotation #### Example scenario [Section titled “Example scenario”](#example-scenario) * The MCP Server stores an API key as `EXTERNAL_API_KEY` in environment variables * When a tool (e.g., `get_weather_data`) is called, your MCP server attaches the key in the request headers * The backend API validates the key and responds with data * The MCP Server processes and returns the formatted response to the client ### Sub-pattern 3b: MCP-to-MCP communication [Section titled “Sub-pattern 3b: MCP-to-MCP communication”](#sub-pattern-3b-mcp-to-mcp-communication) If you have two MCP Servers that need to communicate - for example, `crm-mcp` calling tools from `tickets-mcp` - you can follow the same authentication pattern described in **Pattern 2** above. The calling MCP Server (in this case, `crm-mcp`) acts as an autonomous agent, authenticating with the receiving MCP Server via OAuth 2.1 Client Credentials Flow. Once the token is issued by Scalekit, the calling MCP uses it to call tools exposed by the second MCP Server. #### Authorization sequence [Section titled “Authorization sequence”](#authorization-sequence-3) #### Implementation [Section titled “Implementation”](#implementation-2) The implementation follows Pattern 2 (Agent/Machine → MCP): 1. Create an M2M client for the receiving MCP server in Scalekit 2. Configure the calling MCP server with the client credentials 3. Request tokens using the Client Credentials flow 4. Call the receiving MCP’s tools with the Bearer token For detailed implementation guidance, refer to the [Pattern 2 section](#pattern-2-agent--machine-interacting-with-mcp-server) above. ### Sub-pattern 3c: Cascading the same token [Section titled “Sub-pattern 3c: Cascading the same token”](#sub-pattern-3c-cascading-the-same-token) In some cases, you may want your MCP Server to forward (or “cascade”) the same access token it received from the client - for example, when your backend system lies within the same trust boundary as the Scalekit Authorization Server and can validate the token based on its issuer, scopes, and expiry. #### Authorization sequence [Section titled “Authorization sequence”](#authorization-sequence-4) #### When to use this pattern [Section titled “When to use this pattern”](#when-to-use-this-pattern-1) Use token cascading when: * Both systems (MCP Server and backend API) trust the same Authorization Server (Scalekit) * The backend API can validate JWTs using public keys or JWKS URL * Scopes and issuer claims (`iss`, `scope`, `exp`) are sufficient to determine access * You need to preserve the original user context across service boundaries Trust boundary consideration Only cascade tokens across services that share the same trust boundary. If your backend API does not validate Scalekit-issued tokens, use a separate service credential or the Client Credentials flow (sub-pattern 3b) instead. #### Implementation requirements [Section titled “Implementation requirements”](#implementation-requirements) For the backend API to validate cascaded tokens: 1. Configure the backend to validate JWT signatures using Scalekit’s public keys 2. Verify the token’s `iss` (issuer) claim matches your Scalekit environment 3. Check the `aud` (audience) claim includes the backend API’s identifier 4. Validate the `exp` (expiration) claim to reject expired tokens 5. Verify required scopes are present in the token’s `scope` claim ## Choosing the right pattern [Section titled “Choosing the right pattern”](#choosing-the-right-pattern) Use this decision guide to select the appropriate authentication pattern for your use case: **For human users accessing MCP tools:** → Use **Pattern 1: Human → MCP** (Authorization Code Flow) **For autonomous agents or scheduled tasks:** → Use **Pattern 2: Agent/Machine → MCP** (Client Credentials Flow) **For MCP server making backend calls:** * External APIs with their own auth → Use **Pattern 3a: API Keys** * Another MCP server you control → Use **Pattern 3b: MCP-to-MCP** (Client Credentials Flow) * Backend within same trust boundary → Use **Pattern 3c: Token Cascading** ## Next steps [Section titled “Next steps”](#next-steps) Now that you understand the authentication patterns, you can: * Follow the [MCP OAuth 2.1 quickstart](/authenticate/mcp/quickstart/) to implement Pattern 1 or Pattern 2 * Explore framework-specific implementations: * [FastMCP quickstart](/authenticate/mcp/fastmcp-quickstart/) for Python with built-in provider * [FastAPI + FastMCP quickstart](/authenticate/mcp/fastapi-fastmcp-quickstart/) for custom Python middleware * [Express.js quickstart](/authenticate/mcp/expressjs-quickstart/) for Node.js/TypeScript servers * Review the [MCP authentication demos](https://github.com/scalekit-inc/mcp-auth-demos) on GitHub for complete working examples --- # DOCUMENT BOUNDARY --- # MCP Auth code samples > MCP Auth authentication examples and patterns ### [Add Auth to Node.js MCP Servers](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-node) [Add Scalekit auth to a Node.js MCP server with minimal setup. Includes a working example with user greeting.](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-node) ### [Add Auth to Python MCP Servers](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-python) [Add Scalekit auth to a Python MCP server in minutes. Includes a working example with user greeting.](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-python) ### [Secure FastMCP Apps with Auth](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/todo-fastmcp) [Build a secure FastMCP app with Scalekit. Features a complete todo list with protected endpoints and session management.](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/todo-fastmcp) --- # DOCUMENT BOUNDARY --- # Bring your own auth into your MCP server > Federated authentication system with Scalekit's OAuth 2.1 authorization layer for MCP servers If you already have an authentication system in place, you can use Scalekit as a drop-in OAuth 2.1 authorization layer for your MCP servers. This federated approach allows you to maintain your existing auth infrastructure while adding standards-compliant OAuth 2.1 authorization for MCP clients. **Why use federated authentication?** * **Preserve existing auth**: Keep your current authentication system and user management * **Standards compliance**: Add OAuth 2.1 authorization without rebuilding your auth layer * **Seamless integration**: Users authenticate with your familiar login experience * **Centralized control**: Maintain full control over user authentication and policies When an MCP client initiates authentication, Scalekit acts as a bridge between the MCP client and your existing authentication system. The flow involves redirecting users to your login endpoint, validating their identity, and passing user information back to Scalekit to complete the OAuth 2.1 flow. 1. ## Initiate authentication flow [Section titled “Initiate authentication flow”](#initiate-authentication-flow) When the MCP client starts the authentication flow by calling `/oauth/authorize` on Scalekit, Scalekit redirects the user to your configured login endpoint with two critical parameters: * `login_request_id` string : Unique identifier for this login request * `state` string : OAuth state parameter to maintain security across requests **Example redirect URL:** ```sh https:///login?login_request_id=&state= ``` The login request and its `state` stay valid for approximately 10 minutes. Complete authentication and send the callback to Scalekit within that window. If the request expires, Scalekit shows an `invalid_state` error page and the connection must be restarted from the MCP client. 2. ## Authenticate the user in your system [Section titled “Authenticate the user in your system”](#authenticate-the-user-in-your-system) When the user lands on your login page, process authentication using your existing logic?whether that’s username/password, SSO, biometric authentication, or any other method your system supports. After successful authentication, make a secure backend-to-backend POST request to Scalekit with the authenticated user’s information. Send user details to Scalekit ```bash curl --location '/api/v1/connections//auth-requests//user' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer ' \ --data-raw '{ "sub": "1234567890", "email": "alice@example.com", "given_name": "Alice", "family_name": "Doe", "email_verified": true, "phone_number": "+1234567890", "phone_number_verified": false, "name": "Alice Doe", "preferred_username": "alice.d", "picture": "https://example.com/avatar.jpg", "gender": "female", "locale": "en-US" }' ``` 3. ## Redirect back to Scalekit [Section titled “Redirect back to Scalekit”](#redirect-back-to-scalekit) After receiving a successful response from Scalekit confirming the user details were accepted, redirect the user back to Scalekit’s callback endpoint with the `state` parameter. **Callback URL format:** ```sh /sso/v1/connections//partner:callback?state= ``` The `state_value` must match the `state` parameter you received in step 1. This ensures the authentication flow’s integrity and prevents CSRF attacks. State validation Always verify that the `state` value you send back matches exactly what you received initially. Mismatched state values should be rejected. 4. ## Complete the OAuth flow [Section titled “Complete the OAuth flow”](#complete-the-oauth-flow) After processing the callback from your authentication system, Scalekit automatically handles the remaining OAuth 2.1 flow steps: * Displays the consent screen to the user (if required) * Generates the authorization code * Handles token exchange requests from the MCP client * Issues access tokens with appropriate scopes The MCP client receives valid OAuth 2.1 tokens and can now access your MCP server with the authenticated user’s identity. Your MCP server now supports federated authentication with your existing auth system ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) --- # DOCUMENT BOUNDARY --- # Publish your MCP connector to Claude & ChatGPT > Give MCP connector directory reviewers a test user and static code so they can authenticate and test your server end to end. To list your MCP connector in the [Claude connector directory](https://claude.com/docs/connectors/building/submission) or the [ChatGPT app directory](https://developers.openai.com/apps-sdk/deploy/submission#review-and-approval-faqs), a reviewer must sign in to your server and run every tool end to end. Both submission forms have a testing-access step that expects every credential and step needed to reach a fully-populated account. Scalekit’s [Test Users](/authenticate/run-e2e-tests/) feature makes this possible without handing over a real inbox: allowlist a reviewer email and set a **static 6-digit code**, and the reviewer signs in through Scalekit’s hosted login using that code. This page shows how to prepare the credential and write the instructions to paste into the submission form. Works only with Scalekit-managed auth Test Users works only when **Scalekit manages your app’s login, sessions, and user management** (Full Stack Auth / SaaSKit), because it intercepts Scalekit’s own Magic Link/OTP delivery. It does **not** work when your MCP server runs in [Bring Your Own Auth](/mcp/auth-methods/custom-auth/) mode. In that mode Scalekit federates to your own identity provider and never owns the login screen or the OTP, so there is no static code to hand a reviewer. For Bring Your Own Auth, create a reviewer account directly in your identity provider and share those credentials instead. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * An MCP connector already protected with Scalekit MCP Auth using Scalekit-managed auth. See the [MCP Auth quickstart](/authenticate/mcp/quickstart/). * The **Magic Link & OTP** auth method enabled, with delivery set to `Verification Code` or `Magic Link + Verification Code`. `Magic Link`-only delivery is not supported. See the [Test Users prerequisite](/authenticate/run-e2e-tests/#prerequisites). ## How reviewer sign-in works [Section titled “How reviewer sign-in works”](#how-reviewer-sign-in-works) The reviewer follows the same OAuth 2.1 flow as any [human interacting with your MCP server](/authenticate/mcp/overview/#the-authorization-flow-in-practice): 1. The MCP client (MCP Inspector or Claude as a custom connector) calls your protected server and receives a `401` pointing to Scalekit. 2. The client redirects the reviewer to Scalekit’s hosted login. 3. The reviewer enters the **test email** and the **static code** you configured — no inbox required. 4. The reviewer approves the consent screen, Scalekit issues an access token, and the client runs your tools. ## Prepare the reviewer credential [Section titled “Prepare the reviewer credential”](#prepare-the-reviewer-credential) 1. ## Enable Test Users and add a reviewer email [Section titled “Enable Test Users and add a reviewer email”](#enable-test-users-and-add-a-reviewer-email) In **Dashboard > Environment settings > Test users**, toggle **Enable test users** and add a reviewer address. The email must contain `+sktest` in the local part — for example `reviewer+sktest@yourapp.com`. Set the **Static confirmation code** (the default is `424242`). For the full field-by-field reference, see [Configure test users](/authenticate/run-e2e-tests/#configure-test-users). 2. ## Create the reviewer inside a fully-populated organization [Section titled “Create the reviewer inside a fully-populated organization”](#create-the-reviewer-inside-a-fully-populated-organization) Reviewers expect your tools to return real data, so add the reviewer user to an organization that already has representative content. Create the user with `sendInvitationEmail: false` so no email goes out, then confirm the same email is on the Test Users allowlist. * Node.js Create the reviewer user ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 3 const scalekit = new ScalekitClient( 4 process.env.SCALEKIT_ENVIRONMENT_URL!, 5 process.env.SCALEKIT_CLIENT_ID!, 6 process.env.SCALEKIT_CLIENT_SECRET! 7 ) 8 9 try { 10 // Add the reviewer to a populated org so tools return real data during review. 11 const { user } = await scalekit.user.createUserAndMembership(orgId, { 12 email: 'reviewer+sktest@yourapp.com', 13 sendInvitationEmail: false, 14 }) 15 } catch (error) { 16 console.error('Failed to create reviewer user:', error) 17 } ``` * Python Create the reviewer user ```python 1 import os 2 from scalekit import ScalekitClient 3 from scalekit.v1.users.users_pb2 import CreateUser 4 5 scalekit_client = ScalekitClient( 6 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 7 client_id=os.environ["SCALEKIT_CLIENT_ID"], 8 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], 9 ) 10 11 try: 12 # Add the reviewer to a populated org so tools return real data during review. 13 user_response = scalekit_client.users.create_user_and_membership( 14 org_id, 15 CreateUser(email="reviewer+sktest@yourapp.com"), 16 send_invitation_email=False, 17 ) 18 except Exception as error: 19 print(f"Failed to create reviewer user: {error}") ``` * Go Create the reviewer user ```go 1 import usersv1 "github.com/scalekit-inc/scalekit-sdk-go/v2/pkg/grpc/scalekit/v1/users" 2 3 scalekitClient := scalekit.NewScalekitClient( 4 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 5 os.Getenv("SCALEKIT_CLIENT_ID"), 6 os.Getenv("SCALEKIT_CLIENT_SECRET"), 7 ) 8 9 // Add the reviewer to a populated org so tools return real data during review. 10 userResp, err := scalekitClient.User().CreateUserAndMembership(ctx, orgID, 11 &usersv1.CreateUser{Email: "reviewer+sktest@yourapp.com"}, 12 false, 13 ) 14 if err != nil { 15 log.Fatalf("failed to create reviewer user: %v", err) 16 } ``` * Java Create the reviewer user ```java 1 import com.scalekit.grpc.scalekit.v1.users.*; 2 3 ScalekitClient scalekitClient = new ScalekitClient( 4 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 5 System.getenv("SCALEKIT_CLIENT_ID"), 6 System.getenv("SCALEKIT_CLIENT_SECRET") 7 ); 8 9 try { 10 // Add the reviewer to a populated org so tools return real data during review. 11 CreateUserAndMembershipRequest request = CreateUserAndMembershipRequest.newBuilder() 12 .setUser(CreateUser.newBuilder().setEmail("reviewer+sktest@yourapp.com").build()) 13 .setSendInvitationEmail(false) 14 .build(); 15 16 CreateUserAndMembershipResponse userResp = scalekitClient.users() 17 .createUserAndMembership(orgId, request); 18 } catch (Exception error) { 19 System.err.println("Failed to create reviewer user: " + error.getMessage()); 20 } ``` ## Verify [Section titled “Verify”](#verify) Connect to your server the same way the reviewer will — via [MCP Inspector](https://github.com/modelcontextprotocol/inspector) or as a custom connector in Claude — and sign in with the reviewer email and static code. Verification succeeds when: * Sign-in completes with the static code and no real verification email is sent. * Every tool runs successfully and returns representative data from the populated organization. Fix any gaps before you submit to a directory. ## Write the test setup instructions [Section titled “Write the test setup instructions”](#write-the-test-setup-instructions) Paste instructions into the submission form’s testing-access field — the **Test setup instructions** box on Claude’s **Test & launch** step, or the equivalent testing-instructions field in the ChatGPT app submission. Give the reviewer everything needed to authenticate autonomously: Test setup instructions (paste-ready) ```text Connector URL: https://mcp.yourapp.com/mcp Authentication: OAuth 2.0 (hosted login). When prompted to connect, use the test account below — no email inbox is required. Email: reviewer+sktest@yourapp.com Verification code: 424242 Steps: 1. Add the connector and start the OAuth sign-in. 2. On the login screen, enter the email above and continue. 3. At the verification-code prompt, enter 424242 and continue. 4. Approve the consent screen. 5. The account belongs to a fully-populated organization, so every tool returns representative data. ``` Replace the URL, email, and code with your own values. Keep the code identical to the **Static confirmation code** configured in the dashboard. ## Next steps [Section titled “Next steps”](#next-steps) Once your connector is approved, remove the reviewer email from the allowlist or rotate the static code — see [Configure test users](/authenticate/run-e2e-tests/#configure-test-users) for how to manage the allowlist. ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) --- # DOCUMENT BOUNDARY --- # Express.js quickstart > Build a production-ready Express.js MCP server with TypeScript, custom middleware for OAuth token validation, and Scalekit authentication. This guide shows you how to build a production-ready Express.js MCP server with TypeScript and Scalekit’s OAuth authentication. You’ll implement custom middleware for token validation, expose OAuth resource metadata for client discovery, and create MCP tools that enforce authorization using the MCP SDK. Use this quickstart when you’re building Node.js-based MCP servers and want fine-grained control over request handling. The Express integration gives you flexibility to add custom routes, middleware chains, integrate with existing Express applications, and handle complex authorization requirements. The full code is available on [GitHub](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-node). **Prerequisites** * A [Scalekit account](https://app.scalekit.com) with permission to manage MCP servers * **Node.js 20+** installed locally * Familiarity with Express.js, TypeScript, and OAuth token validation * Basic understanding of MCP server architecture 1. ## Register your MCP server in Scalekit [Section titled “Register your MCP server in Scalekit”](#register-your-mcp-server-in-scalekit) Create a protected resource entry so Scalekit can issue tokens that your custom Express middleware validates. 1. Navigate to **[Dashboard](https://app.scalekit.com) > MCP Servers > Add MCP Server**. 2. Enter a descriptive name (for example, `Greeting MCP`). 3. Set **Server URL** to `http://localhost:3002/` (keep the trailing slash). 4. Click **Save** to create the server. ![Greeting MCP Register](/.netlify/images?url=_astro%2Fgreeting-mcp-register.C9jsKOBy.png\&w=836\&h=1314\&dpl=6aaa70ad2ea7b40008ad2afd) When you save, Scalekit displays the OAuth-protected resource metadata. Copy this JSON—you’ll use it in your `.env` file. ![Greeting MCP Protected JSON](/.netlify/images?url=_astro%2Fgreeting-protected-json.DaFlRuyP.png\&w=716\&h=860\&dpl=6aaa70ad2ea7b40008ad2afd) 2. ## Create your project directory [Section titled “Create your project directory”](#create-your-project-directory) Set up a clean directory structure for your TypeScript Express project. Terminal ```bash 1 mkdir express-mcp-node 2 cd express-mcp-node ``` 3. ## Add package dependencies [Section titled “Add package dependencies”](#add-package-dependencies) Create a `package.json` with scripts and all required dependencies for Express, TypeScript, and the MCP SDK. Terminal ```bash 1 cat <<'EOF' > package.json 2 { 3 "name": "express-mcp-node", 4 "version": "1.0.0", 5 "type": "module", 6 "scripts": { 7 "dev": "tsx src/server.ts", 8 "build": "tsc", 9 "start": "node dist/server.js" 10 }, 11 "dependencies": { 12 "@modelcontextprotocol/sdk": "^1.13.0", 13 "@scalekit-sdk/node": "^2.0.1", 14 "cors": "^2.8.5", 15 "dotenv": "^16.4.5", 16 "express": "^5.1.0", 17 "zod": "^3.25.57" 18 }, 19 "devDependencies": { 20 "@types/cors": "^2.8.19", 21 "@types/express": "^4.17.21", 22 "@types/node": "^20.11.19", 23 "tsx": "^4.7.0", 24 "typescript": "^5.4.5" 25 } 26 } 27 EOF ``` 4. ## Configure TypeScript [Section titled “Configure TypeScript”](#configure-typescript) Add a TypeScript configuration file optimized for ES2022 modules and strict type checking. Terminal ```bash 1 cat <<'EOF' > tsconfig.json 2 { 3 "compilerOptions": { 4 "target": "ES2022", 5 "module": "ES2022", 6 "moduleResolution": "node", 7 "esModuleInterop": true, 8 "forceConsistentCasingInFileNames": true, 9 "strict": false, 10 "skipLibCheck": true, 11 "resolveJsonModule": true, 12 "outDir": "dist", 13 "rootDir": "src", 14 "types": ["node"] 15 }, 16 "include": ["src/**/*"] 17 } 18 EOF ``` 5. ## Install dependencies [Section titled “Install dependencies”](#install-dependencies) Install all packages declared in `package.json`. Terminal ```bash 1 npm install ``` 6. ## Configure environment variables [Section titled “Configure environment variables”](#configure-environment-variables) Create a `.env` file with your Scalekit credentials and the protected resource metadata from step 1. Terminal ```bash 1 cat <<'EOF' > .env 2 PORT=3002 3 SK_ENV_URL=https://.scalekit.com 4 SK_CLIENT_ID= 5 SK_CLIENT_SECRET= 6 MCP_SERVER_ID= 7 PROTECTED_RESOURCE_METADATA='' 8 EXPECTED_AUDIENCE=http://localhost:3002/ 9 EOF 10 11 open .env ``` | Variable | Description | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `PORT` | Local port for the Express server. Must match the Server URL registered in Scalekit (defaults to `3002`). | | `SK_ENV_URL` | Your Scalekit environment URL from **Dashboard > Settings > API Credentials** | | `SK_CLIENT_ID` | Client ID from **Dashboard > Settings > API Credentials**. Used with `SK_CLIENT_SECRET` to initialize the SDK. | | `SK_CLIENT_SECRET` | Client secret from **Dashboard > Settings > API Credentials**. Keep this secret and rotate regularly. | | `MCP_SERVER_ID` | The MCP server ID from **Dashboard > MCP Servers**. Not directly used in this implementation but documented for reference. | | `PROTECTED_RESOURCE_METADATA` | The complete OAuth resource metadata JSON from step 1. Clients use this to discover authorization requirements. | | `EXPECTED_AUDIENCE` | The audience value that tokens must include. Should match your server’s public URL (e.g., `http://localhost:3002/`). | Protect your credentials Never commit `.env` to version control. Add it to `.gitignore` immediately and use a secret manager in production (e.g., AWS Secrets Manager, HashiCorp Vault, or your deployment platform’s secrets service). 7. ## Implement the Express MCP server [Section titled “Implement the Express MCP server”](#implement-the-express-mcp-server) Create `src/server.ts` with the complete server implementation. This includes the Scalekit client initialization, authentication middleware for token validation, CORS configuration, and the greeting MCP tool. src/server.ts ```typescript 1 import 'dotenv/config'; 2 import cors from 'cors'; 3 import express, { NextFunction, Request, Response } from 'express'; 4 import { z } from 'zod'; 5 import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 6 import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; 7 import { Scalekit } from '@scalekit-sdk/node'; 8 9 // Load environment variables 10 const PORT = Number(process.env.PORT ?? 3002); 11 const SK_ENV_URL = process.env.SK_ENV_URL ?? ''; 12 const SK_CLIENT_ID = process.env.SK_CLIENT_ID ?? ''; 13 const SK_CLIENT_SECRET = process.env.SK_CLIENT_SECRET ?? ''; 14 const EXPECTED_AUDIENCE = process.env.EXPECTED_AUDIENCE ?? ''; 15 const PROTECTED_RESOURCE_METADATA = process.env.PROTECTED_RESOURCE_METADATA ?? ''; 16 17 // Use case: Configure OAuth resource metadata URL for MCP clients 18 // This allows MCP clients to discover authorization requirements via WWW-Authenticate header 19 // Security: The WWW-Authenticate header signals to clients where to obtain tokens 20 const RESOURCE_METADATA_URL = `http://localhost:${PORT}/.well-known/oauth-protected-resource`; 21 22 // WWW-Authenticate header for 401 responses 23 const WWW_HEADER_KEY = 'WWW-Authenticate'; 24 const WWW_HEADER_VALUE = `Bearer realm="OAuth", resource_metadata="${RESOURCE_METADATA_URL}"`; 25 26 // Initialize Scalekit client for token validation 27 // Security: Use SDK to validate JWT signatures and claims 28 // This prevents accepting forged or tampered tokens 29 const scalekit = new Scalekit(SK_ENV_URL, SK_CLIENT_ID, SK_CLIENT_SECRET); 30 31 // Initialize MCP server with greeting tool 32 // Context: The McpServer handles MCP protocol details while Express handles HTTP routing 33 const server = new McpServer({ name: 'Greeting MCP', version: '1.0.0' }); 34 35 // Use case: Simple greeting tool demonstrating OAuth-protected MCP operations 36 // Context: This tool is protected by the authentication middleware applied to all routes 37 server.tool( 38 'greet_user', 39 'Greets the user with a personalized message.', 40 { 41 name: z.string().min(1, 'Name is required'), 42 }, 43 async ({ name }: { name: string }) => ({ 44 content: [ 45 { 46 type: 'text', 47 text: `Hi ${name}, welcome to Scalekit!` 48 } 49 ] 50 }) 51 ); 52 53 // Initialize Express application 54 const app = express(); 55 56 // Enable CORS for cross-origin MCP clients 57 // Use case: Allow MCP clients from different origins to connect 58 app.use(cors({ origin: true, credentials: false })); 59 60 // Parse JSON request bodies 61 // Context: MCP protocol uses JSON-RPC format 62 app.use(express.json()); 63 64 // Use case: Expose OAuth resource metadata for MCP client discovery 65 // This endpoint allows clients to discover authorization requirements and server capabilities 66 // Context: MCP clients use this metadata to initiate the OAuth flow 67 app.get('/.well-known/oauth-protected-resource', (_req: Request, res: Response) => { 68 if (!PROTECTED_RESOURCE_METADATA) { 69 res.status(500).json({ error: 'PROTECTED_RESOURCE_METADATA config missing' }); 70 return; 71 } 72 73 const metadata = JSON.parse(PROTECTED_RESOURCE_METADATA); 74 res.type('application/json').send(JSON.stringify(metadata, null, 2)); 75 }); 76 77 // Use case: Health check endpoint for monitoring and load balancers 78 // Context: Keep this separate from protected endpoints for deployment health checks 79 app.get('/health', (_req: Request, res: Response) => { 80 res.json({ status: 'healthy' }); 81 }); 82 83 // Security: Validate Bearer tokens on all protected endpoints 84 // Public endpoints (health, metadata) are exempt from authentication 85 // This prevents unauthorized access to MCP tools and operations 86 app.use(async (req: Request, res: Response, next: NextFunction) => { 87 // Allow public endpoints without authentication 88 // Use case: Health checks for monitoring; metadata for client discovery 89 if (req.path === '/.well-known/oauth-protected-resource' || req.path === '/health') { 90 next(); 91 return; 92 } 93 94 // Extract Bearer token from Authorization header 95 // Use case: OAuth 2.1 Bearer token format (RFC 6750) 96 // Security: Reject requests without valid Bearer token prefix 97 const header = req.headers.authorization; 98 const token = header?.startsWith('Bearer ') 99 ? header.slice('Bearer '.length).trim() 100 : undefined; 101 102 if (!token) { 103 res.status(401) 104 .set(WWW_HEADER_KEY, WWW_HEADER_VALUE) 105 .json({ error: 'Missing Bearer token' }); 106 return; 107 } 108 109 try { 110 // Validate token using Scalekit SDK 111 // Security: Verifies signature, expiration, issuer, and audience claims 112 // Context: This critical step prevents accepting tokens from other issuers 113 await scalekit.validateToken(token, { audience: [EXPECTED_AUDIENCE] }); 114 next(); 115 } catch (error) { 116 res.status(401) 117 .set(WWW_HEADER_KEY, WWW_HEADER_VALUE) 118 .json({ error: 'Token validation failed' }); 119 } 120 }); 121 122 // Handle MCP protocol requests at root path 123 // Use case: Process authenticated MCP tool requests using StreamableHTTPServerTransport 124 // Context: The transport layer handles MCP JSON-RPC communication 125 app.post('/', async (req: Request, res: Response) => { 126 const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined }); 127 await server.connect(transport); 128 129 try { 130 await transport.handleRequest(req, res, req.body); 131 } catch (error) { 132 res.status(500).json({ error: 'MCP transport error' }); 133 } 134 }); 135 136 // Start the Express server 137 app.listen(PORT, () => { 138 console.log(`MCP server running on http://localhost:${PORT}`); 139 }); ``` 8. ## Start the Express server [Section titled “Start the Express server”](#start-the-express-server) Start the Express server in development mode with auto-reload enabled. The server will listen on `http://localhost:3002/` and display logs indicating Express is ready to receive authenticated MCP requests. Terminal ```bash 1 npm run dev ``` The server starts on `http://localhost:3002/` and logs indicate Express is ready. The MCP endpoint at `/` accepts authenticated POST requests, and the metadata endpoint is accessible at `/.well-known/oauth-protected-resource`. 9. ## Connect with MCP Inspector [Section titled “Connect with MCP Inspector”](#connect-with-mcp-inspector) Test your server end-to-end using the MCP Inspector to verify the OAuth flow works correctly. This allows you to see the authentication handshake and test calling your MCP tools with validated tokens. Terminal ```bash 1 npx @modelcontextprotocol/inspector@latest ``` In the Inspector UI: 1. Enter your MCP Server URL: `http://localhost:3002/` 2. Click **Connect** to initiate the OAuth flow 3. Authenticate with Scalekit when prompted 4. Run the `greet_user` tool with any name ![MCP Inspector](/.netlify/images?url=_astro%2Fmcp-inspector-google.B0jhj-ep.png\&w=3022\&h=1318\&dpl=6aaa70ad2ea7b40008ad2afd) You now have a working Express.js MCP server with Scalekit-protected OAuth authentication. Extend this implementation by adding more MCP tools using `server.tool()` with Zod schema validation, implementing scope-based authorization using custom middleware, integrating with your existing Express application, or adding features like rate limiting and request logging using Express’s middleware ecosystem. --- # DOCUMENT BOUNDARY --- # FastAPI + FastMCP quickstart > Build a production-ready MCP server with FastAPI custom middleware for OAuth token validation and Scalekit authentication. This guide shows you how to build a production-ready FastAPI + FastMCP server with Scalekit’s OAuth authentication. You’ll implement custom middleware for token validation, expose OAuth resource metadata for client discovery, and create MCP tools that enforce authorization. Use this quickstart when you need more control over your server’s behavior than FastMCP’s built-in provider offers. The FastAPI integration gives you flexibility to add custom middleware, implement additional endpoints, integrate with existing FastAPI applications, and handle complex authorization requirements. The full code is available on [GitHub](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-python). **Prerequisites** * A [Scalekit account](https://app.scalekit.com) with permission to manage MCP servers * **Python 3.11+** installed locally * Familiarity with FastAPI and OAuth token validation * Basic understanding of MCP server architecture 1. ## Register your MCP server in Scalekit [Section titled “Register your MCP server in Scalekit”](#register-your-mcp-server-in-scalekit) Create a protected resource entry so Scalekit can issue tokens that your custom FastAPI middleware validates. 1. Navigate to **[Dashboard](https://app.scalekit.com) > MCP Servers > Add MCP Server**. 2. Enter a descriptive name (for example, `Greeting MCP`). 3. Set **Server URL** to `http://localhost:3002/` (keep the trailing slash). 4. Click **Save** to create the server. ![Greeting MCP Register](/.netlify/images?url=_astro%2Fgreeting-mcp-register.C9jsKOBy.png\&w=836\&h=1314\&dpl=6aaa70ad2ea7b40008ad2afd) When you save, Scalekit displays the OAuth-protected resource metadata. Copy this JSON—you’ll use it in your `.env` file. ![Greeting MCP Protected JSON](/.netlify/images?url=_astro%2Fgreeting-protected-json.DaFlRuyP.png\&w=716\&h=860\&dpl=6aaa70ad2ea7b40008ad2afd) 2. ## Create your project directory [Section titled “Create your project directory”](#create-your-project-directory) Set up a clean directory structure with a Python virtual environment to isolate FastAPI and FastMCP dependencies. Terminal ```bash 1 mkdir fastapi-mcp-python 2 cd fastapi-mcp-python 3 python3 -m venv .venv 4 source .venv/bin/activate ``` 3. ## Add dependencies [Section titled “Add dependencies”](#add-dependencies) Create a `requirements.txt` file with all required packages and install them. Terminal ```bash 1 cat <<'EOF' > requirements.txt 2 mcp>=1.0.0 3 fastapi>=0.104.0 4 fastmcp>=0.8.0 5 uvicorn>=0.24.0 6 pydantic>=2.5.0 7 python-dotenv>=1.0.0 8 httpx>=0.25.0 9 python-jose[cryptography]>=3.3.0 10 cryptography>=41.0.0 11 scalekit-sdk-python>=2.4.0 12 starlette>=0.27.0 13 EOF 14 15 pip install -r requirements.txt ``` 4. ## Configure environment variables [Section titled “Configure environment variables”](#configure-environment-variables) Create a `.env` file with your Scalekit credentials and the protected resource metadata from step 1. Terminal ```bash 1 cat <<'EOF' > .env 2 PORT=3002 3 SK_ENV_URL=https://.scalekit.com 4 SK_CLIENT_ID= 5 SK_CLIENT_SECRET= 6 MCP_SERVER_ID= 7 PROTECTED_RESOURCE_METADATA='' 8 EXPECTED_AUDIENCE=http://localhost:3002/ 9 EOF 10 11 open .env ``` | Variable | Description | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `PORT` | Local port for the FastAPI server. Must match the Server URL registered in Scalekit (defaults to `3002`). | | `SK_ENV_URL` | Your Scalekit environment URL from **Dashboard > Settings > API Credentials** | | `SK_CLIENT_ID` | Client ID from **Dashboard > Settings > API Credentials**. Used with `SK_CLIENT_SECRET` to initialize the SDK. | | `SK_CLIENT_SECRET` | Client secret from **Dashboard > Settings > API Credentials**. Keep this secret and rotate regularly. | | `MCP_SERVER_ID` | The MCP server ID from **Dashboard > MCP Servers**. Not directly used in this implementation but documented for reference. | | `PROTECTED_RESOURCE_METADATA` | The complete OAuth resource metadata JSON from step 1. Clients use this to discover authorization requirements. | | `EXPECTED_AUDIENCE` | The audience value that tokens must include. Should match your server’s public URL (e.g., `http://localhost:3002/`). | Protect your credentials Never commit `.env` to version control. Add it to `.gitignore` immediately and use a secret manager in production (e.g., AWS Secrets Manager, HashiCorp Vault, or your deployment platform’s secrets service). 5. ## Implement the FastAPI + FastMCP server [Section titled “Implement the FastAPI + FastMCP server”](#implement-the-fastapi--fastmcp-server) Create `main.py` with the complete server implementation. This includes the Scalekit client initialization, authentication middleware for token validation, CORS configuration, and the greeting MCP tool. main.py ```python 1 import json 2 import os 3 from fastapi import FastAPI, Request, Response 4 from fastmcp import FastMCP, Context 5 from scalekit import ScalekitClient 6 from scalekit.common.scalekit import TokenValidationOptions 7 from starlette.middleware.cors import CORSMiddleware 8 from dotenv import load_dotenv 9 10 load_dotenv() 11 12 # Load environment variables 13 PORT = int(os.getenv("PORT", "3002")) 14 SK_ENV_URL = os.getenv("SK_ENV_URL", "") 15 SK_CLIENT_ID = os.getenv("SK_CLIENT_ID", "") 16 SK_CLIENT_SECRET = os.getenv("SK_CLIENT_SECRET", "") 17 EXPECTED_AUDIENCE = os.getenv("EXPECTED_AUDIENCE", "") 18 PROTECTED_RESOURCE_METADATA = os.getenv("PROTECTED_RESOURCE_METADATA", "") 19 20 # Use case: Configure OAuth resource metadata URL for MCP clients 21 # This allows MCP clients to discover authorization requirements via WWW-Authenticate header 22 # Security: The WWW-Authenticate header signals to clients where to obtain tokens 23 RESOURCE_METADATA_URL = f"http://localhost:{PORT}/.well-known/oauth-protected-resource" 24 WWW_HEADER = { 25 "WWW-Authenticate": f'Bearer realm="OAuth", resource_metadata="{RESOURCE_METADATA_URL}"' 26 } 27 28 # Initialize Scalekit client for token validation 29 # Security: Use SDK to validate JWT signatures and claims 30 # This prevents accepting forged or tampered tokens 31 scalekit_client = ScalekitClient( 32 env_url=SK_ENV_URL, 33 client_id=SK_CLIENT_ID, 34 client_secret=SK_CLIENT_SECRET, 35 ) 36 37 # Initialize FastMCP with stateless HTTP transport 38 # HTTP transport allows MCP clients to connect via standard OAuth flows 39 mcp = FastMCP("Greeting MCP", stateless_http=True) 40 41 42 @mcp.tool( 43 name="greet_user", 44 description="Greets the user with a personalized message." 45 ) 46 async def greet_user(name: str, ctx: Context | None = None) -> dict: 47 """ 48 Use case: Simple greeting tool demonstrating OAuth-protected MCP operations 49 Context: This tool is protected by the authentication middleware 50 """ 51 return { 52 "content": [ 53 { 54 "type": "text", 55 "text": f"Hi {name}, welcome to Scalekit!" 56 } 57 ] 58 } 59 60 61 # Mount FastMCP as a FastAPI application 62 # Context: This allows us to layer FastAPI middleware on top of FastMCP 63 mcp_app = mcp.http_app(path="/") 64 app = FastAPI(lifespan=mcp_app.lifespan) 65 66 # Enable CORS for cross-origin MCP clients 67 # Use case: Allow MCP clients from different origins to connect 68 app.add_middleware( 69 CORSMiddleware, 70 allow_origins=["*"], 71 allow_credentials=True, 72 allow_methods=["GET", "POST", "OPTIONS"], 73 allow_headers=["*"] 74 ) 75 76 77 @app.middleware("http") 78 async def auth_middleware(request: Request, call_next): 79 """ 80 Security: Validate Bearer tokens on all protected endpoints. 81 Public endpoints (health, metadata) are exempt from authentication. 82 This prevents unauthorized access to MCP tools and operations. 83 """ 84 # Allow public endpoints without authentication 85 # Use case: Health checks for monitoring; metadata for client discovery 86 if request.url.path in {"/health", "/.well-known/oauth-protected-resource"}: 87 return await call_next(request) 88 89 # Extract Bearer token from Authorization header 90 # Use case: OAuth 2.1 Bearer token format (RFC 6750) 91 # Security: Reject requests without valid Bearer token prefix 92 auth_header = request.headers.get("authorization") 93 if not auth_header or not auth_header.startswith("Bearer "): 94 return Response( 95 '{"error": "Missing Bearer token"}', 96 status_code=401, 97 headers=WWW_HEADER, 98 media_type="application/json" 99 ) 100 101 token = auth_header.split("Bearer ", 1)[1].strip() 102 103 # Validate token using Scalekit SDK 104 # Security: Verifies signature, expiration, issuer, and audience claims 105 # Context: This critical step prevents accepting tokens from other issuers 106 options = TokenValidationOptions( 107 issuer=SK_ENV_URL, 108 audience=[EXPECTED_AUDIENCE] 109 ) 110 111 try: 112 is_valid = scalekit_client.validate_access_token(token, options=options) 113 if not is_valid: 114 raise ValueError("Invalid token") 115 except Exception: 116 return Response( 117 '{"error": "Token validation failed"}', 118 status_code=401, 119 headers=WWW_HEADER, 120 media_type="application/json" 121 ) 122 123 # Token is valid, proceed with request 124 # This allows MCP clients to call tools with authenticated context 125 return await call_next(request) 126 127 128 @app.get("/.well-known/oauth-protected-resource") 129 async def oauth_metadata(): 130 """ 131 Use case: Expose OAuth resource metadata for MCP client discovery 132 This endpoint allows clients to discover authorization requirements and server capabilities 133 Context: MCP clients use this metadata to initiate the OAuth flow 134 """ 135 if not PROTECTED_RESOURCE_METADATA: 136 return Response( 137 '{"error": "PROTECTED_RESOURCE_METADATA config missing"}', 138 status_code=500, 139 media_type="application/json" 140 ) 141 142 metadata = json.loads(PROTECTED_RESOURCE_METADATA) 143 return Response( 144 json.dumps(metadata, indent=2), 145 media_type="application/json" 146 ) 147 148 149 @app.get("/health") 150 async def health_check(): 151 """ 152 Use case: Health check endpoint for monitoring and load balancers 153 Context: Keep this separate from protected endpoints for deployment health checks 154 """ 155 return {"status": "healthy"} 156 157 158 # Mount the FastMCP application at root path 159 app.mount("/", mcp_app) 160 161 162 if __name__ == "__main__": 163 import uvicorn 164 # Start server with auto-reload for development 165 # Production: Use 'uvicorn main:app --host 0.0.0.0 --port 3002 --workers 4' behind a reverse proxy 166 uvicorn.run(app, host="0.0.0.0", port=PORT) ``` 6. ## Start the FastAPI server [Section titled “Start the FastAPI server”](#start-the-fastapi-server) Start the FastAPI server in development mode with auto-reload enabled. The server will listen on `http://localhost:3002/` and display logs indicating FastAPI is ready to receive authenticated MCP requests. Terminal ```bash 1 python main.py ``` The server starts on `http://localhost:3002/` and logs indicate FastAPI is ready. The MCP endpoint accepts authenticated requests, and the metadata endpoint is accessible at `/.well-known/oauth-protected-resource`. 7. ## Connect with MCP Inspector [Section titled “Connect with MCP Inspector”](#connect-with-mcp-inspector) Test your server end-to-end using the MCP Inspector to verify the OAuth flow works correctly. This allows you to see the authentication handshake and test calling your MCP tools with validated tokens. Terminal ```bash 1 npx @modelcontextprotocol/inspector@latest ``` In the Inspector UI: 1. Enter your MCP Server URL: `http://localhost:3002/` 2. Click **Connect** to initiate the OAuth flow 3. Authenticate with Scalekit when prompted 4. Run the `greet_user` tool with any name ![MCP Inspector](/.netlify/images?url=_astro%2Fmcp-inspector-google.B0jhj-ep.png\&w=3022\&h=1318\&dpl=6aaa70ad2ea7b40008ad2afd) You now have a working FastAPI + FastMCP server with Scalekit-protected OAuth authentication. Extend this implementation by adding more MCP tools with the `@mcp.tool` decorator, implementing scope-based authorization using custom middleware, integrating with your existing FastAPI application, or adding features like rate limiting and request logging using FastAPI’s middleware pipeline. --- # DOCUMENT BOUNDARY --- # FastMCP quickstart > FastMCP todo server with OAuth scope validation and CRUD operations. This guide shows you how to build a production-ready FastMCP server protected by Scalekit’s OAuth authentication. You’ll register your server as a protected resource, implement scope-based authorization for CRUD operations, and validate tokens on every request. Use this quickstart to experience a working reference implementation with a simple todo application. The todo app demonstrates how to enforce `todo:read` and `todo:write` scopes across multiple tools. After completing this guide, you can apply the same authentication pattern to secure your own FastMCP tools. The full code is available on [GitHub](https://github.com/scalekit-inc/mcp-demo/tree/main/todo-fastmcp). **Prerequisites** * A [Scalekit account](https://app.scalekit.com) with permission to manage MCP servers * **Python 3.11+** installed locally * Familiarity with OAuth scopes and basic terminal commands 1. ## Register your MCP server in Scalekit [Section titled “Register your MCP server in Scalekit”](#register-your-mcp-server-in-scalekit) Create a protected resource entry so Scalekit can issue scoped tokens that FastMCP validates on every request. 1. Navigate to **[Dashboard](https://app.scalekit.com) > MCP Servers > Add MCP Server**. 2. Enter a descriptive name (for example, `FastMCP Todo Server`). 3. Set **Server URL** to `http://localhost:3002/` (keep the trailing slash). This field is a required.\ For a server running at `http://localhost:3002/mcp`, register `http://localhost:3002/`. FastMCP appends `/mcp` automatically, so always provide the base URL with a trailing slash. 4. Create or link the scopes below, then click **Save**. ![Register FastMCP server](/.netlify/images?url=_astro%2Fregister-fastmcp.yj75FoPt.png\&w=772\&h=1316\&dpl=6aaa70ad2ea7b40008ad2afd) | Scope | Description | Required | | ------------ | -------------------------------------------- | -------- | | `todo:read` | Grants read access to todo tasks | Yes | | `todo:write` | Allows creating, updating, or deleting tasks | Yes | 2. ## Create your FastMCP todo server [Section titled “Create your FastMCP todo server”](#create-your-fastmcp-todo-server) Prepare a fresh directory and virtual environment to keep FastMCP dependencies isolated. Terminal ```bash 1 mkdir -p fastmcp-todo 2 cd fastmcp-todo 3 python3 -m venv venv 4 source venv/bin/activate ``` 3. ## Add dependencies and configuration templates [Section titled “Add dependencies and configuration templates”](#add-dependencies-and-configuration-templates) Create the support files that FastMCP and Scalekit expect, then install the required libraries. Terminal ```bash 1 cat <<'EOF' > requirements.txt 2 fastmcp>=2.13.0.2 3 python-dotenv>=1.0.0 4 EOF 5 6 pip install -r requirements.txt 7 8 cat <<'EOF' > env.example 9 PORT=3002 10 SCALEKIT_ENVIRONMENT_URL=https://your-environment-url.scalekit.com 11 SCALEKIT_CLIENT_ID=your_client_id 12 SCALEKIT_RESOURCE_ID=mcp_server_id 13 MCP_URL=http://localhost:3002/ 14 EOF ``` 4. ## Implement the FastMCP todo server [Section titled “Implement the FastMCP todo server”](#implement-the-fastmcp-todo-server) Copy the following code into `server.py`. It registers the Scalekit provider, defines an in-memory todo store, and exposes CRUD tools guarded by OAuth scopes. server.py ```python 1 """Scalekit-authenticated FastMCP server providing in-memory CRUD tools for todos. 2 3 This example demonstrates how to protect FastMCP tools with OAuth scopes. 4 Each tool validates the required scope before executing operations. 5 """ 6 7 import os 8 import uuid 9 from dataclasses import dataclass, asdict 10 from typing import Optional 11 12 from dotenv import load_dotenv 13 from fastmcp import FastMCP 14 from fastmcp.server.auth.providers.scalekit import ScalekitProvider 15 from fastmcp.server.dependencies import AccessToken, get_access_token 16 17 load_dotenv() 18 19 # Use case: Configure FastMCP server with OAuth protection 20 # Security: Scalekit provider validates every request's Bearer token 21 mcp = FastMCP( 22 "Todo Server", 23 stateless_http=True, 24 auth=ScalekitProvider( 25 environment_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 26 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 27 resource_id=os.getenv("SCALEKIT_RESOURCE_ID"), 28 # FastMCP appends /mcp automatically; keep base URL with trailing slash only 29 mcp_url=os.getenv("MCP_URL"), 30 ), 31 ) 32 33 34 @dataclass 35 class TodoItem: 36 id: str 37 title: str 38 description: Optional[str] 39 completed: bool = False 40 41 def to_dict(self) -> dict: 42 return asdict(self) 43 44 45 # Use case: In-memory storage for demo purposes 46 # Production: Replace with your database or persistent storage 47 _TODO_STORE: dict[str, TodoItem] = {} 48 49 50 def _require_scope(scope: str) -> Optional[str]: 51 """ 52 Security: Validate that the current request's token includes the required scope. 53 This prevents unauthorized access to protected operations. 54 """ 55 token: AccessToken = get_access_token() 56 if scope not in token.scopes: 57 return f"Insufficient permissions: `{scope}` scope required." 58 return None 59 60 61 @mcp.tool 62 def create_todo(title: str, description: Optional[str] = None) -> dict: 63 """ 64 Use case: Create a new todo item for task tracking 65 Requires: todo:write scope 66 """ 67 error = _require_scope("todo:write") 68 if error: 69 return {"error": error} 70 71 todo = TodoItem(id=str(uuid.uuid4()), title=title, description=description) 72 _TODO_STORE[todo.id] = todo 73 return {"todo": todo.to_dict()} 74 75 76 @mcp.tool 77 def list_todos(completed: Optional[bool] = None) -> dict: 78 """ 79 Use case: Retrieve all todos, optionally filtered by completion status 80 Requires: todo:read scope 81 """ 82 error = _require_scope("todo:read") 83 if error: 84 return {"error": error} 85 86 todos = [ 87 todo.to_dict() 88 for todo in _TODO_STORE.values() 89 if completed is None or todo.completed == completed 90 ] 91 return {"todos": todos} 92 93 94 @mcp.tool 95 def get_todo(todo_id: str) -> dict: 96 """ 97 Use case: Retrieve a specific todo by ID 98 Requires: todo:read scope 99 """ 100 error = _require_scope("todo:read") 101 if error: 102 return {"error": error} 103 104 todo = _TODO_STORE.get(todo_id) 105 if todo is None: 106 return {"error": f"Todo `{todo_id}` not found."} 107 108 return {"todo": todo.to_dict()} 109 110 111 @mcp.tool 112 def update_todo( 113 todo_id: str, 114 title: Optional[str] = None, 115 description: Optional[str] = None, 116 completed: Optional[bool] = None, 117 ) -> dict: 118 """ 119 Use case: Update existing todo properties or mark as complete 120 Requires: todo:write scope 121 """ 122 error = _require_scope("todo:write") 123 if error: 124 return {"error": error} 125 126 todo = _TODO_STORE.get(todo_id) 127 if todo is None: 128 return {"error": f"Todo `{todo_id}` not found."} 129 130 if title is not None: 131 todo.title = title 132 if description is not None: 133 todo.description = description 134 if completed is not None: 135 todo.completed = completed 136 137 return {"todo": todo.to_dict()} 138 139 140 @mcp.tool 141 def delete_todo(todo_id: str) -> dict: 142 """ 143 Use case: Remove a todo from the system 144 Requires: todo:write scope 145 """ 146 error = _require_scope("todo:write") 147 if error: 148 return {"error": error} 149 150 todo = _TODO_STORE.pop(todo_id, None) 151 if todo is None: 152 return {"error": f"Todo `{todo_id}` not found."} 153 154 return {"deleted": todo_id} 155 156 157 if __name__ == "__main__": 158 # Start HTTP transport server 159 mcp.run(transport="http", port=int(os.getenv("PORT", "3002"))) ``` 5. ## Provide runtime secrets [Section titled “Provide runtime secrets”](#provide-runtime-secrets) Copy the environment template and populate the values from your Scalekit dashboard. Terminal ```bash 1 cp env.example .env 2 open .env ``` | Variable | Description | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `SCALEKIT_ENVIRONMENT_URL` | Your Scalekit environment URL, labeled **Environment URL** in **Dashboard > Settings > API Credentials** | | `SCALEKIT_CLIENT_ID` | Client ID from **Dashboard > Settings > API Credentials** | | `SCALEKIT_RESOURCE_ID` | The resource identifier assigned to your MCP server (starts with `res_`). Find it on your MCP server’s detail page in the dashboard. | | `MCP_URL` | The base public URL you registered (keep trailing slash, e.g., `http://localhost:3002/`) | | `PORT` | Local port for FastMCP HTTP transport (defaults to `3002`) | Store secrets securely Avoid committing `.env` to source control. Use your team’s secret manager in production and rotate credentials if they appear in logs or terminal history. 6. ## Run the FastMCP server locally [Section titled “Run the FastMCP server locally”](#run-the-fastmcp-server-locally) Start the server so it can accept authenticated MCP requests at `/mcp`. Terminal ```bash 1 source venv/bin/activate 2 python server.py ``` When the server boots successfully, you’ll see FastMCP announce the HTTP transport and listen on `http://localhost:3002/`, ready to enforce Scalekit-issued tokens. ![Run MCP server](/.netlify/images?url=_astro%2Fvenv-activate-fastmcp.UYaMwNRn.png\&w=2986\&h=926\&dpl=6aaa70ad2ea7b40008ad2afd) 7. ## Connect with an MCP client [Section titled “Connect with an MCP client”](#connect-with-an-mcp-client) Use any MCP-compatible client to exercise the todo tools with scoped tokens. During development, the MCP Inspector demonstrates how the Scalekit provider enforces scopes end-to-end. Terminal ```bash 1 npx @modelcontextprotocol/inspector@latest ``` In the Inspector UI, point the client to `http://localhost:3002/mcp` and click **Connect**. The client initiates OAuth authentication with Scalekit. After successful authentication, run any tool—the server exposes `create_todo`, `list_todos`, `get_todo`, `update_todo`, and `delete_todo`. ![MCP Inspector](/.netlify/images?url=_astro%2Fmcp-inspector-fastmcp.CcqqKz2X.png\&w=3024\&h=1502\&dpl=6aaa70ad2ea7b40008ad2afd) Once you’re satisfied with the quickstart example, extend `server.py` with your own FastMCP tools or replace the in-memory store with your production data source. Scalekit’s provider handles authentication for any toolset you add. --- # DOCUMENT BOUNDARY --- # New to MCP? > Lock down MCP connections with OAuth 2.1 so agents get only the access they need AI systems are moving beyond chatbots to agents that act in the real world. They handle sensitive data and run complex workflows. As they grow, they need a secure, standard way to connect. The Model Context Protocol (MCP) provides that standard. It defines how AI applications safely discover and use external tools and data. MCP incorporates OAuth 2.1 authorization mechanisms at the transport level. This enables MCP clients to make secure requests to restricted MCP servers on behalf of resource owners. | Features | Benefit | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | Industry standard | Well-established authorization framework with extensive tooling and ecosystem support | | Security best practices | Incorporates improvements over OAuth 2.0, removing deprecated flows and enforcing security measures like PKCE | | Multiple grant types | Supports different use cases: **Authorization code** for human user scenarios and **Client credentials** for machine-to-machine integrations | | Ecosystem compatibility | Integrates with existing identity providers and authorization servers | ## Complete MCP OAuth 2.1 flow [Section titled “Complete MCP OAuth 2.1 flow”](#complete-mcp-oauth-21-flow) Here’s the complete end-to-end authorization flow showing all phases from discovery to token refresh in a single sequence diagram: ### Understanding the MCP authorization flow [Section titled “Understanding the MCP authorization flow”](#understanding-the-mcp-authorization-flow) MCP OAuth 2.1 provides secure, standardized authorization for AI agents accessing protected resources. The flow establishes trust, authenticates users, authorizes access, and maintains security throughout the session lifecycle by building each phase on the previous one. --- # DOCUMENT BOUNDARY --- # Production readiness checklist > A focused checklist for launching your MCP server authentication, with emphasis on custom domain and branding for a production-grade OAuth consent experience. As you prepare to launch MCP server authentication to production, verify these items before going live. ## Production environment [Section titled “Production environment”](#production-environment) **Verify production environment configuration** Confirm that your environment URL (`SCALEKIT_ENVIRONMENT_URL`), client ID (`SCALEKIT_CLIENT_ID`), and client secret (`SCALEKIT_CLIENT_SECRET`) are correctly set for production, not dev or staging. ## Custom domain (CNAME) [Section titled “Custom domain (CNAME)”](#custom-domain-cname) Configuring a custom domain is the highest-impact step for MCP auth. Without it, the OAuth consent screen your users see during authorization displays `yourapp.scalekit.com` (Scalekit’s default domain) instead of your own brand. Complete this section before you test any end-to-end auth flows in production. **Configure a custom domain in the Scalekit dashboard** Go to **Dashboard > Auth for SaaS > Customization > Custom Domain** and follow the CNAME setup instructions. CNAME configuration is available only in production environments. See [Branded custom domains](/guides/custom-domain/) for step-by-step instructions. **Verify SSL certificate provisioning** After CNAME verification, Scalekit automatically provisions an SSL certificate. Click **Check** in **Dashboard > Auth for SaaS > Customization > Custom Domain** to confirm status. Provisioning can take up to 24 hours. Contact if it takes longer. **Update customer-facing authorization URLs to use your custom domain** Backend API calls work with either URL, but the authorization URL and any other endpoints your users interact with must use your custom domain (for example, `mcp.yourapp.com`) for branding to take effect. Update those URLs in your application code after CNAME setup is complete. **Confirm the consent screen shows your branded domain** Open an incognito window, trigger an authorization flow, and verify the OAuth consent screen shows your custom domain (for example, `mcp.yourapp.com`) and not the default Scalekit URL. ## Consent screen branding [Section titled “Consent screen branding”](#consent-screen-branding) **Upload your logo and set brand colors** Go to **Dashboard > Auth for SaaS > Customization > Branding** to upload your logo, set a favicon, and configure background colors. This is what users see during the OAuth authorization flow. **Set a recognizable MCP server name** When registering your MCP server in **Dashboard > MCP Servers**, provide a name that users will recognize (for example, `Acme Calendar`, not `mcp-prod-v2`). This name appears on the consent page that MCP hosts display to users when they authorize access. ## Bring your own auth (if applicable) [Section titled “Bring your own auth (if applicable)”](#bring-your-own-auth-if-applicable) If you are using a federated authentication setup where Scalekit acts as the OAuth 2.1 layer but delegates user authentication to your existing system, verify these additional items. **Configure your login endpoint URL in the Scalekit dashboard** Scalekit redirects users to your login endpoint with a `login_request_id` and `state` parameter. Confirm the endpoint URL is correctly set for your production environment. **Verify your login endpoint handles the `login_request_id` and `state` parameters** Your login page must capture both parameters from the redirect and pass them through the authentication flow. Missing either parameter breaks the callback handshake. **Test the backend-to-backend user handoff** After authenticating a user, your system POSTs user attributes to Scalekit at `/api/v1/connections//auth-requests//user`. Verify this call succeeds with production credentials and that the `connection_id` (starts with `conn_`) is correct for your production MCP server. **Verify the state parameter in your callback redirect** After the user handoff, your system redirects back to Scalekit’s callback URL with the `state` value from step 1. Confirm the values match exactly. Mismatched state is silently rejected and breaks the flow. **Test the complete federated flow end-to-end** Trigger a full authorization flow from an MCP client through your login page, the user handoff API call, and the callback redirect, and verify the MCP client receives a valid access token at the end. See [Bring your own auth](/authenticate/mcp/custom-auth/) for implementation details. ## Core auth flows [Section titled “Core auth flows”](#core-auth-flows) **Test the human → MCP authorization flow end-to-end** After CNAME and branding are configured, trigger a complete authorization code flow: from the initial tool call through the `401` challenge, consent screen, token exchange, and authorized response. Run this in production with your live credentials. **Test the agent → MCP client credentials flow** Verify that API clients can obtain tokens and call MCP tools successfully. Confirm that client credentials are stored in environment variables or a secrets manager, not hardcoded. ## Monitoring [Section titled “Monitoring”](#monitoring) **Enable auth logs and set up alerts** Monitor **Dashboard > Auth Logs** for repeated `401` errors, invalid scope requests, and token failures after launch. Set up alerts for unusual activity patterns. After launch, use [Auth logs](/guides/dashboard/auth-logs/) to debug authentication issues and review the [MCP auth troubleshooting guide](/authenticate/mcp/troubleshooting/) for common problems. --- # DOCUMENT BOUNDARY --- # Managing MCP Clients > Manage MCP clients by viewing registered MCP clients, tracking user consent, and revoking access to your MCP servers. To maintain security and control over your MCP Server, you need to manage which client applications can access it. Scalekit provides several ways for clients to connect, including automatic registration for modern apps and manual pre-registration for custom or trusted clients. This guide covers the different types of MCP clients and shows you how to: * View all registered clients * See which users have granted consent to a client * Revoke user access for any client There are three main categories of MCP Clients that can interact with your MCP Server: ## 1. Automatic registration with DCR [Section titled “1. Automatic registration with DCR”](#1-automatic-registration-with-dcr) These are MCP Clients that automatically register themselves as OAuth clients. Most modern MCP clients, such as Claude Desktop, OpenAI, VS Code, and Cursor, support Dynamic Client Registration (DCR). They initiate the registration process and start the OAuth Authorization flow with the Scalekit server to obtain an access token without requiring manual configuration. During the consent flow, users see your **environment domain** as the requesting identifier — not “Scalekit” and not your application name. This is by design: the domain identifies the authorization server handling the request, similar to how Google OAuth shows the requesting domain. To display a custom branded domain, configure a [custom domain](/agentkit/advanced/custom-domain) for your Scalekit environment. ## 2. Manual client pre-registration [Section titled “2. Manual client pre-registration”](#2-manual-client-pre-registration) These are MCP Clients that you manually register in the Scalekit Dashboard. This is useful when you want to restrict access to specific, pre-approved clients or when you are building a custom client that requires fixed credentials. You can create OAuth clients that can either act as themselves or on behalf of the user. ### How to pre-register a client [Section titled “How to pre-register a client”](#how-to-pre-register-a-client) If you need to manually register an MCP Client, you can do so in the Scalekit Dashboard. 1. Navigate to the **Clients** section of your MCP Server. 2. Click the **Create Client** button. ![Create Client](/_astro/mcp_create_client.lIT_Y1hO.png) **Configuration:** * **Client name**: A display name (e.g., “My Custom Client”). * **Redirect URI**: The URL where the client will redirect users after authorization. 3. **Choosing the right OAuth flow:** * **For Client Credentials Flow**: Leave the Redirect URI field empty. Your application will authenticate using only the `client_id` and `client_secret`. This is suitable for server-to-server communication. * **For Authorization Code Grant Flow**: Provide one or more Redirect URIs where users will be redirected after granting consent. This is required for user-facing applications that need to act on behalf of users. **Cross-App Access (XAA):** XAA doesn’t require any explicit setting - your static clients by default support cross-app access under enterprise plan. Once the client is created, you will receive a `client_id` and `client_secret` to configure in your application. ![Redirect URI](/_astro/mcp_configure_client.CQDvSRQa.png) ### 2.1 OAuth client credential flow [Section titled “2.1 OAuth client credential flow”](#21-oauth-client-credential-flow) Use this flow when your MCP Client needs to act on its own behalf rather than on behalf of a specific user. This is ideal for machine-to-machine communication scenarios. **When to use:** * Backend services or server-side applications * Automated scripts or batch processes * System integrations that don’t require user interaction * Applications that need to access resources without user context **Characteristics:** * No user interaction required * No redirect URI needed * Client authenticates using `client_id` and `client_secret` * Access token represents the client itself ### 2.2 OAuth authorization code grant flow [Section titled “2.2 OAuth authorization code grant flow”](#22-oauth-authorization-code-grant-flow) Use this flow when your MCP Client needs to act on behalf of a user. This is the standard OAuth flow that requires user consent. **When to use:** * User-facing applications (web, desktop, or mobile) * Applications that need to access user-specific resources * Scenarios requiring explicit user consent * Applications where actions should be attributed to specific users **Characteristics:** * Requires user authentication and consent * Redirect URI is mandatory * Client receives authorization code, exchanges it for access token * Access token represents the user’s authorization ## 3. Registration via metadata URL (CIMD) [Section titled “3. Registration via metadata URL (CIMD)”](#3-registration-via-metadata-url-cimd) These are MCP Clients that support Client ID Metadata Document (CIMD), an OAuth 2.0 mechanism that allows clients to use a URL as their client identifier. When a CIMD-compatible client initiates the OAuth flow, Scalekit fetches the client’s metadata (such as name, redirect URIs, and other registration information) from the provided URL. This provides an alternative registration method without requiring manual pre-registration or Dynamic Client Registration, making it easier for clients to authenticate across different authorization servers. ## Manage registered clients [Section titled “Manage registered clients”](#manage-registered-clients) ### View all registered clients [Section titled “View all registered clients”](#view-all-registered-clients) You can view a list of all MCP Clients that have been registered with your MCP Server (both DCR and pre-registered) in the Scalekit Dashboard. 1. Go to your MCP Server in the dashboard. 2. Click on the **Clients** tab. ![View all MCP Clients](/.netlify/images?url=_astro%2Fview_all_clients.ClEAh2pi.png\&w=2544\&h=896\&dpl=6aaa70ad2ea7b40008ad2afd) ### View consented users [Section titled “View consented users”](#view-consented-users) For each registered MCP Client that uses the OAuth Authorization Code Grant Flow, you can view all users who have granted consent. 1. From the **Clients** list, click on a specific client. 2. Navigate to the **Consents** tab to see the list of users who have authorized this client. ![View Consented Users](/.netlify/images?url=_astro%2Fview_consented_users.bNB41DHP.png\&w=2050\&h=1500\&dpl=6aaa70ad2ea7b40008ad2afd) To audit the same consents from your own admin screens, list them with the Node SDK. See [Resource consents](/saaskit/sdks/node/resources/). ### Revoke user access [Section titled “Revoke user access”](#revoke-user-access) As an administrator, you can revoke a user’s consent for a specific MCP Client at any time. This is useful when: * A user requests to revoke access * You need to remove access for security reasons * An employee leaves the organization * You want to force re-authentication **To revoke access:** 1. Navigate to the specific MCP Client from the **Clients** list. 2. Go to the **Consents** tab. 3. Find the user whose access you want to revoke. 4. Click the **Revoke** or **Delete** action for that user. Once revoked, the user will need to go through the authorization flow again to grant consent if they want to use the MCP Client. To revoke a consent programmatically, call `revokeUserConsent` in the Node SDK. See [Resource consents](/saaskit/sdks/node/resources/). ### Revoke access from a public MCP client [Section titled “Revoke access from a public MCP client”](#revoke-access-from-a-public-mcp-client) On Scalekit, MCP clients registered through Dynamic Client Registration (`DCR`) or a Client ID Metadata Document (`CIMD`) are public clients: they have no client secret. Scalekit’s OAuth token revocation endpoint requires client authentication, so a direct revoke call from these clients returns `invalid_client`. That response is expected, not a misconfiguration. To revoke access, use one of the supported paths instead: * **Revoke consent from the dashboard**: revoke the user’s consent from the **Consents** tab, as described in [Revoke user access](/authenticate/mcp/managing-mcp-clients/#revoke-user-access). * **Disconnect in the client**: most MCP clients expose a **Disconnect** action that clears tokens stored on the client. This is local sign-out only; it does not revoke the grant on Scalekit. * **Revoke the session in your own system**: when you use [Bring your own auth](/authenticate/mcp/custom-auth/), revoke the user’s session in your auth system. After your MCP server rejects that session, the next request returns `401 Unauthorized` and the client must authenticate again. ### How revocation affects active access tokens [Section titled “How revocation affects active access tokens”](#how-revocation-affects-active-access-tokens) Revoking consent or ending a session stops Scalekit from issuing **new** access tokens for that user, but it does not cancel an access token that was already issued. The existing token keeps working until it expires. This is expected behavior, not a vulnerability. Scalekit issues access tokens as self-contained JWTs. Your MCP server validates each token locally against Scalekit’s public keys and does not call back to the authorization server on every request, so Scalekit cannot reach out and cancel a token that is already in circulation. Every OAuth server that issues self-contained JWTs behaves this way. The exposure is bounded by the time left on the token — its `exp` claim. To shrink or close that window, use either approach: * **Shorten the access token lifetime.** Lower the **Access token lifetime** for the MCP server at **Dashboard > MCP servers > your server > Access token lifetime** (you can also set it when you [add an MCP server](/authenticate/mcp/quickstart/); the recommended range is 300–3600 seconds). You can also set it per client. A shorter lifetime means a revoked token stops working sooner. This MCP server setting is separate from the access token lifetime configured for a Web Application — changing the Web Application setting does not affect tokens minted for this MCP server. * **Maintain a token denylist.** Validate the token with the Scalekit SDK as you do today, then check its `jti` claim against a denylist before serving the request, and reject the request when the `jti` is present. Store each revoked `jti` with a time-to-live equal to the token’s remaining lifetime — for example, a Redis key that expires at the token’s `exp`. This gives near-immediate revocation at the cost of one lookup per request. --- # DOCUMENT BOUNDARY --- # Agent / Machine interacting with MCP Server > Learn how an autonomous agent or machine securely authenticates with an MCP Server using OAuth 2.1 Client Credentials flow in Scalekit. An **autonomous agent** or any **machine-to-machine process** can directly interact with an **MCP Server** secured by Scalekit. In this model, the agent acts as a **confidential OAuth client**, authenticated using a `client_id` and `client_secret` issued by Scalekit. This topology uses the **OAuth 2.1 Client Credentials flow**, allowing the agent to obtain an access token without user interaction. Tokens are scoped and time-bound, ensuring secure and auditable automation between services. *** ## Authorization Sequence [Section titled “Authorization Sequence”](#authorization-sequence) *** ## How It Works [Section titled “How It Works”](#how-it-works) **Client Registration** Before an agent can request tokens, you must create a **Machine-to-Machine (M2M) client** for your MCP Server in Scalekit. Steps to create a client: 1. Navigate to **Dashboard ? MCP Servers** and select your MCP Server. Go to the **Clients** tab. ![Clients tab placeholder](/.netlify/images?url=_astro%2Fmcp-client-nav.C6UPUhIu.png\&w=1148\&h=1242\&dpl=6aaa70ad2ea7b40008ad2afd) 2. Click **Create Client**. ![Create client placeholder](/.netlify/images?url=_astro%2Fmcp-clients-tab.UgPaVUGm.png\&w=3020\&h=1040\&dpl=6aaa70ad2ea7b40008ad2afd) 3. Copy the **client\_id** and **client\_secret** immediately - the secret will not be shown again. ![Client Sidesheet](/.netlify/images?url=_astro%2Fmcp-client-sidesheet.D9KN4b5q.png\&w=3020\&h=1500\&dpl=6aaa70ad2ea7b40008ad2afd) 4. Optionally, set scopes (e.g., `todo:read`, `todo:write`) that correspond to the permissions configured for your MCP Server. Hit **Save** *** ## Requesting an Access Token [Section titled “Requesting an Access Token”](#requesting-an-access-token) Once you have the client credentials, the agent can request a token directly from the Scalekit Authorization Server: Terminal ```bash 1 curl --location '{{env_url}}/oauth/token' \ 2 --header 'Content-Type: application/x-www-form-urlencoded' \ 3 --data-urlencode 'grant_type=client_credentials' \ 4 --data-urlencode 'client_id={{client_id}}' \ 5 --data-urlencode 'client_secret={{secret_value}}' \ 6 --data-urlencode 'scope=todo:read todo:write' ``` Scalekit responds with a JSON payload similar to: ```json 1 { 2 "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIn0...", 3 "token_type": "Bearer", 4 "expires_in": 3600, 5 "scope": "todo:read todo:write" 6 } ``` Use the `access_token` in the `Authorization` header when calling your MCP Server’s endpoint. *** ## Try It Yourself [Section titled “Try It Yourself”](#try-it-yourself) If you’d like to simulate this flow, use the same **FastMCP Todo Server** from the [FastMCP Example](/authenticate/mcp/fastmcp-quickstart). Create an **M2M client** in the Scalekit Dashboard and run your token request using `curl` or programmatically within your agent. Once the token is obtained, attach it as a Bearer token in the `Authorization` header when calling your MCP Server’s tools. --- # DOCUMENT BOUNDARY --- # Human interacting with MCP Server > Learn how a human authenticates with an MCP Server via OAuth 2.1 when using MCP-compliant hosts such as ChatGPT, Claude, VSCode, or Windsurf. When a human uses a compliant MCP host, that host acts as the OAuth client. It initiates authorization with the Scalekit Authorization Server, obtains a scoped access token, and interacts securely with the MCP Server on behalf of the user. This topology represents the most common interaction model for real-world MCP usecases - **humans interacting with an MCP**, while Scalekit ensures tokens are valid, scoped, and auditable. *** ## Authorization Sequence [Section titled “Authorization Sequence”](#authorization-sequence) *** ## How It Works [Section titled “How It Works”](#how-it-works) 1. **Initiation** ? The human configures an MCP server in their MCP client. 2. **Challenge** ? The MCP Server responds with an HTTP `401` containing a `WWW-Authenticate` header that points to the Scalekit Authorization Server. 3. **Authorization Flow** ? The MCP Client opens the user’s browser to initiate the OAuth 2.1 authorization flow. During this step, the Scalekit Authorization Server handles user authentication through Passwordless, Passkeys, Social login providers (like Google, GitHub, or LinkedIn), or Enterprise SSO integrations (such as Okta, Microsoft Entra ID, or ADFS). The user is then prompted to grant consent for the requested scopes. Once approved, Scalekit returns an authorization code, which the MCP Client exchanges for an access token. 4. **Token Issuance** ? Scalekit issues an OAuth 2.1 access token containing claims and scopes (for example, `todo:read`, `calendar:write`) that represent the user’s permissions. 5. **Authorized Request** ? The client calls the MCP Server again, now attaching the Bearer token in the `Authorization` header. 6. **Validation and Execution** ? The MCP Server validates the token issued by scalekit and executes the requested tool. *** ## Try It Yourself [Section titled “Try It Yourself”](#try-it-yourself) Head to the **[FastMCP Examples section](/authenticate/mcp/fastmcp-quickstart)** to experience this topology in action. There you’ll register a FastMCP server, configure Scalekit Auth, and observe token issuance and validation end-to-end. --- # DOCUMENT BOUNDARY --- # MCP Server interacting with MCPs / APIs > Understand how an MCP Server integrates with internal systems, other MCP servers, or external APIs using secure tokens or API keys. In real-world scenarios, an **MCP Server** often needs to make backend calls - to your **own APIs**, to **another MCP Server**, or to **external APIs** such as CRM, ticketing, or SaaS tools. This page explains three secure ways to perform these downstream integrations, each corresponding to a different trust boundary and authorization pattern. ## 1. Using API Keys or Custom Tokens [Section titled “1. Using API Keys or Custom Tokens”](#1-using-api-keys-or-custom-tokens) Your MCP Server can communicate with internal or external backend systems that have their own authorization servers or API key?based access. In this setup, the MCP Server manages its own credentials securely (for example, an environment variable, vault, or secrets manager) and injects them when making downstream calls. ### Example [Section titled “Example”](#example) * The MCP Server stores an API key as `EXTERNAL_API_KEY` in environment variables. * When a tool (e.g., `get_weather_data`) is called, your MCP server attaches the key in the request. * The backend API validates the key and responds with data. *** ## 2. Interacting with Another MCP Server autonomously [Section titled “2. Interacting with Another MCP Server autonomously”](#2-interacting-with-another-mcp-server-autonomously) If you have two MCP Servers that need to communicate - for example, `crm-mcp` calling tools from `tickets-mcp` - you can follow the same authentication pattern described in the [Agent ? MCP](/authenticate/mcp/topologies/agent-mcp/) topology. The calling MCP Server (in this case, `crm-mcp`) acts as an **autonomous agent**, authenticating with the receiving MCP Server via **OAuth 2.1 Client Credentials Flow**. Once the token is issued by Scalekit, the calling MCP uses it to call tools exposed by the second MCP Server. You can find a detailed explanation of this topology in [this section](/authenticate/mcp/topologies/agent-mcp). *** ## 3. Cascading the Same Token to Downstream Systems [Section titled “3. Cascading the Same Token to Downstream Systems”](#3-cascading-the-same-token-to-downstream-systems) In some cases, you may want your MCP Server to forward (or “cascade”) the **same access token** it received from the client - for example, when your backend system lies within the same trust boundary as the Scalekit Authorization Server and can validate the token based on its issuer, scopes, and expiry. ### When to Use This Pattern [Section titled “When to Use This Pattern”](#when-to-use-this-pattern) * Both systems (MCP Server and backend MCP/API) trust **the same Authorization Server** (Scalekit). * The backend API can validate JWTs using public keys or JWKS URL. * Scopes and issuer claims (`iss`, `scope`, `exp`) are sufficient to determine access. --- # DOCUMENT BOUNDARY --- # Add auth to xmcp server > Build an MCP server with xmcp framework and Scalekit OAuth 2.1 authentication. xmcp handles transport, routing, and bundling so you focus on tools. This guide shows you how to build an MCP server with [xmcp](https://xmcp.dev) and secure it with Scalekit OAuth 2.1. xmcp is a TypeScript MCP framework that handles transport setup, bundling, and hot reload — you write tools as plain functions and add auth via a middleware file. Use this quickstart when you want a framework that manages MCP protocol details for you. xmcp gives you file-based routing for tools, built-in Streamable HTTP transport, and a middleware convention that keeps auth separate from business logic. The full code is available on [GitHub](https://github.com/scalekit-developers/xmcp-scalekit-example). **Prerequisites** * A [Scalekit account](https://app.scalekit.com) with permission to manage MCP servers * **Node.js 18+** installed locally * Basic understanding of TypeScript and OAuth 1. ## Register your MCP server in Scalekit [Section titled “Register your MCP server in Scalekit”](#register-your-mcp-server-in-scalekit) Create a protected resource entry so Scalekit can issue and validate tokens for your server. 1. Navigate to **[Dashboard](https://app.scalekit.com) > MCP Servers > Add MCP Server**. 2. Enter a descriptive name (for example, `xmcp Demo`). 3. Set **Server URL** to `http://localhost:3001`. 4. Ensure **Allow dynamic client registration** is checked — this is required for MCP clients like Claude Desktop and Cursor to connect automatically. 5. Click **Save** to create the server. After saving, note the **Resource ID** shown below the server name (for example, `res_...`). You’ll need it in the next step. 2. ## Create your project [Section titled “Create your project”](#create-your-project) Scaffold a new xmcp project and add the dependencies for Scalekit authentication. Terminal ```bash 1 mkdir xmcp-scalekit-example 2 cd xmcp-scalekit-example ``` Create `package.json`: package.json ```json 1 { 2 "name": "xmcp-scalekit-example", 3 "private": true, 4 "scripts": { 5 "dev": "xmcp dev", 6 "build": "xmcp build", 7 "start": "node dist/http.js" 8 }, 9 "dependencies": { 10 "xmcp": "^0.6.10", 11 "@scalekit-sdk/node": "^2.6.2", 12 "jose": "^5.2.0", 13 "express": "^4.22.1", 14 "zod": "^4.0.10" 15 }, 16 "devDependencies": { 17 "@types/express": "^4.17.25", 18 "@types/node": "^22.19.2", 19 "typescript": "^5.9.3" 20 } 21 } ``` Install dependencies: Terminal ```bash 1 npm install ``` 3. ## Configure environment variables [Section titled “Configure environment variables”](#configure-environment-variables) Create a `.env` file with your Scalekit credentials from step 1. Terminal ```bash 1 cat <<'EOF' > .env 2 SCALEKIT_ENVIRONMENT_URL=https://.scalekit.com 3 SCALEKIT_CLIENT_ID= 4 SCALEKIT_CLIENT_SECRET= 5 SCALEKIT_RESOURCE_ID= 6 BASE_URL=http://localhost:3001 7 PORT=3001 8 EOF 9 10 open .env ``` | Variable | Description | | -------------------------- | ---------------------------------------------------------------------------------------------- | | `SCALEKIT_ENVIRONMENT_URL` | Your Scalekit environment URL from **Dashboard > Settings > API Credentials** | | `SCALEKIT_CLIENT_ID` | Client ID from **Dashboard > Settings > API Credentials** | | `SCALEKIT_CLIENT_SECRET` | Client secret from **Dashboard > Settings > API Credentials** | | `SCALEKIT_RESOURCE_ID` | Resource ID from **Dashboard > MCP Servers** (the `res_...` value shown below the server name) | | `BASE_URL` | Public URL where your server is reachable. Must match the Server URL registered in Scalekit | | `PORT` | Local port for the server | Resource ID is required Without `SCALEKIT_RESOURCE_ID`, the server cannot serve the resource-specific authorization server metadata that includes the `registration_endpoint`. MCP clients that rely on Dynamic Client Registration (DCR) — including Claude Desktop and Cursor — will fail to connect. 4. ## Enable Streamable HTTP transport [Section titled “Enable Streamable HTTP transport”](#enable-streamable-http-transport) Create `xmcp.config.ts` at the project root to enable Streamable HTTP mode. By default xmcp uses stdio; setting `http: true` starts an Express-based HTTP server. xmcp.config.ts ```typescript 1 import { XmcpConfig } from "xmcp"; 2 3 const config: XmcpConfig = { 4 http: true, 5 paths: { 6 prompts: false, 7 resources: false, 8 }, 9 }; 10 11 export default config; ``` 5. ## Add the Scalekit auth provider [Section titled “Add the Scalekit auth provider”](#add-the-scalekit-auth-provider) Create `src/lib/scalekit-auth.ts` — this is the auth provider that handles JWT verification and OAuth discovery endpoints. The provider returns an xmcp `Middleware` object with a `router` (for discovery endpoints) and a `middleware` (for token validation on `/mcp`). src/lib/scalekit-auth.ts ```typescript 1 import { 2 Router, 3 Request, 4 Response, 5 NextFunction, 6 type RequestHandler, 7 } from "express"; 8 import { createContext, type Middleware } from "xmcp"; 9 import { createRemoteJWKSet, jwtVerify, errors } from "jose"; 10 import { Scalekit } from "@scalekit-sdk/node"; 11 12 // --- Types --- 13 14 export interface ScalekitConfig { 15 readonly environmentUrl: string; 16 readonly clientId: string; 17 readonly clientSecret: string; 18 readonly baseURL: string; 19 readonly resourceId?: string; 20 readonly docsURL?: string; 21 readonly scopes?: readonly string[]; 22 } 23 24 export interface JWTClaims { 25 readonly sub: string; 26 readonly iss: string; 27 readonly aud?: string | readonly string[]; 28 readonly exp: number; 29 readonly iat: number; 30 readonly scope?: string; 31 readonly sid?: string; 32 readonly org_id?: string; 33 } 34 35 export interface Session { 36 readonly userId: string; 37 readonly scopes: readonly string[]; 38 readonly organizationId?: string; 39 readonly expiresAt: Date; 40 readonly issuedAt: Date; 41 readonly claims: JWTClaims; 42 } 43 44 interface SessionContext { 45 session: Session | null; 46 } 47 48 interface ClientContext { 49 client: Scalekit; 50 } 51 52 const sessionContext = createContext({ 53 name: "scalekit-context-session", 54 }); 55 56 const clientContext = createContext({ 57 name: "scalekit-context-client", 58 }); 59 60 // --- Public accessors (call from tools) --- 61 62 export function getSession(): Session { 63 const ctx = sessionContext.getContext(); 64 if (!ctx.session) { 65 throw new Error( 66 "[Scalekit] No session. Is the request authenticated?" 67 ); 68 } 69 return ctx.session; 70 } 71 72 export function getClient(): Scalekit { 73 const { client } = clientContext.getContext(); 74 if (!client) { 75 throw new Error( 76 "[Scalekit] Client not initialized." 77 ); 78 } 79 return client; 80 } 81 82 // --- JWT helpers --- 83 84 async function verifyScalekitToken( 85 token: string, 86 jwksUrl: URL, 87 issuer: string 88 ) { 89 const JWKS = createRemoteJWKSet(jwksUrl); 90 const { payload } = await jwtVerify(token, JWKS, { 91 issuer, 92 clockTolerance: 30, 93 }); 94 if (!payload.sub) throw new Error("Missing sub claim"); 95 return payload as unknown as JWTClaims; 96 } 97 98 function claimsToSession(claims: JWTClaims): Session { 99 return { 100 userId: claims.sub, 101 scopes: claims.scope ? claims.scope.split(" ") : [], 102 organizationId: claims.org_id, 103 expiresAt: new Date(claims.exp * 1000), 104 issuedAt: new Date(claims.iat * 1000), 105 claims, 106 }; 107 } 108 109 function extractBearerToken( 110 header: string | undefined 111 ): string | null { 112 if (!header) return null; 113 const parts = header.split(" "); 114 if (parts.length !== 2 || parts[0].toLowerCase() !== "bearer") 115 return null; 116 return parts[1]; 117 } 118 119 // --- Provider factory --- 120 121 export function scalekitProvider( 122 config: ScalekitConfig 123 ): Middleware { 124 const client = new Scalekit( 125 config.environmentUrl, 126 config.clientId, 127 config.clientSecret 128 ); 129 130 clientContext.provider({ client }, () => {}); 131 sessionContext.provider({ session: null }, () => {}); 132 133 const envUrl = config.environmentUrl.replace(/\/$/, ""); 134 const authServerBase = config.resourceId 135 ? `${envUrl}/resources/${config.resourceId}` 136 : envUrl; 137 138 // Pre-fetch JWKS URI — try OAuth AS metadata first. 139 // Resource-specific paths serve /.well-known/oauth-authorization-server 140 // but NOT /.well-known/openid-configuration. 141 let resolvedJwksUri: URL | null = null; 142 (async () => { 143 try { 144 const urls = [ 145 `${authServerBase}/.well-known/oauth-authorization-server`, 146 `${authServerBase}/.well-known/openid-configuration`, 147 ]; 148 for (const url of urls) { 149 const response = await fetch(url); 150 if (response.ok) { 151 const meta = (await response.json()) as { 152 jwks_uri?: string; 153 }; 154 if (meta.jwks_uri) { 155 resolvedJwksUri = new URL(meta.jwks_uri); 156 console.log( 157 "[Scalekit] Resolved JWKS URI:", 158 resolvedJwksUri.toString() 159 ); 160 return; 161 } 162 } 163 } 164 } catch (e) { 165 console.warn("[Scalekit] Could not pre-fetch JWKS URI:", e); 166 } 167 })(); 168 169 return { 170 middleware: buildMiddleware( 171 config, 172 authServerBase, 173 () => resolvedJwksUri 174 ), 175 router: buildRouter(config, authServerBase), 176 }; 177 } 178 179 // --- Router (discovery endpoints) --- 180 181 function buildRouter( 182 config: ScalekitConfig, 183 authServerBase: string 184 ): Router { 185 const router = Router(); 186 const baseUrl = config.baseURL.replace(/\/$/, ""); 187 188 // RFC 9728: Protected Resource Metadata 189 router.get( 190 "/.well-known/oauth-protected-resource", 191 (_req: Request, res: Response) => { 192 res.json({ 193 resource: baseUrl, 194 authorization_servers: [authServerBase], 195 bearer_methods_supported: ["header"], 196 ...(config.scopes && 197 config.scopes.length > 0 && { 198 scopes_supported: config.scopes, 199 }), 200 }); 201 } 202 ); 203 204 // RFC 8414: Authorization Server Metadata (proxied from Scalekit) 205 // Tries /.well-known/oauth-authorization-server first because 206 // resource-specific paths include registration_endpoint for DCR. 207 router.get( 208 "/.well-known/oauth-authorization-server", 209 async (_req: Request, res: Response) => { 210 try { 211 const asUrl = `${authServerBase}/.well-known/oauth-authorization-server`; 212 const asRes = await fetch(asUrl); 213 if (asRes.ok) { 214 res.json(await asRes.json()); 215 return; 216 } 217 const oidcUrl = `${authServerBase}/.well-known/openid-configuration`; 218 const oidcRes = await fetch(oidcUrl); 219 if (oidcRes.ok) { 220 res.json(await oidcRes.json()); 221 return; 222 } 223 res.status(502).json({ 224 error: "Failed to fetch authorization server metadata", 225 }); 226 } catch { 227 res.status(502).json({ 228 error: "Failed to fetch authorization server metadata", 229 }); 230 } 231 } 232 ); 233 234 return router; 235 } 236 237 // --- Middleware (token validation) --- 238 239 function buildMiddleware( 240 config: ScalekitConfig, 241 authServerBase: string, 242 getJwksUri: () => URL | null 243 ): RequestHandler { 244 const wwwAuth = 245 'Bearer resource_metadata="/.well-known/oauth-protected-resource"'; 246 247 return async ( 248 req: Request, 249 res: Response, 250 next: NextFunction 251 ) => { 252 if (!req.path.startsWith("/mcp")) { 253 next(); 254 return; 255 } 256 257 const token = extractBearerToken(req.headers.authorization); 258 if (!token) { 259 res.setHeader("WWW-Authenticate", wwwAuth); 260 res.status(401).json({ 261 error: "unauthorized", 262 error_description: "Missing or invalid bearer token", 263 }); 264 return; 265 } 266 267 try { 268 const jwksUrl = 269 getJwksUri() || 270 new URL(`${authServerBase}/.well-known/jwks`); 271 272 // Validate against environmentUrl — Scalekit always sets 273 // the environment URL as the JWT issuer, not the 274 // resource-specific path. 275 const claims = await verifyScalekitToken( 276 token, 277 jwksUrl, 278 config.environmentUrl.replace(/\/$/, "") 279 ); 280 281 const session = claimsToSession(claims); 282 sessionContext.provider({ session }, () => next()); 283 } catch { 284 res.setHeader( 285 "WWW-Authenticate", 286 `${wwwAuth}, error="invalid_token"` 287 ); 288 res.status(401).json({ 289 error: "invalid_token", 290 error_description: "Token verification failed", 291 }); 292 } 293 }; 294 } ``` Three details that are easy to get wrong: * **JWKS resolution:** Resource-specific paths on Scalekit serve `/.well-known/oauth-authorization-server` but return 404 for `/.well-known/openid-configuration`. The provider tries both in order. * **AS metadata proxy:** The resource-specific `oauth-authorization-server` response includes the `registration_endpoint` that DCR clients need. The environment-level `openid-configuration` does not. * **Issuer validation:** Scalekit JWTs always have the environment URL as `iss`, not the resource-specific path. The middleware validates against `config.environmentUrl`, not `authServerBase`. 6. ## Wire the middleware [Section titled “Wire the middleware”](#wire-the-middleware) Create `src/middleware.ts` — this is the file xmcp looks for to apply auth middleware to all requests. src/middleware.ts ```typescript 1 import { scalekitProvider } from "./lib/scalekit-auth"; 2 3 export default scalekitProvider({ 4 environmentUrl: process.env.SCALEKIT_ENVIRONMENT_URL!, 5 clientId: process.env.SCALEKIT_CLIENT_ID!, 6 clientSecret: process.env.SCALEKIT_CLIENT_SECRET!, 7 baseURL: process.env.BASE_URL || "http://localhost:3001", 8 resourceId: process.env.SCALEKIT_RESOURCE_ID, 9 scopes: ["openid", "profile", "email"], 10 }); ``` 7. ## Add tools [Section titled “Add tools”](#add-tools) xmcp uses file-based routing — each file in `src/tools/` becomes an MCP tool. Create two tools that use the authenticated session. src/tools/whoami.ts ```typescript 1 import { type ToolMetadata } from "xmcp"; 2 import { getSession } from "../lib/scalekit-auth"; 3 4 export const metadata: ToolMetadata = { 5 name: "whoami", 6 description: 7 "Returns the authenticated user's session information", 8 }; 9 10 export default function whoami(): string { 11 const session = getSession(); 12 return JSON.stringify( 13 { 14 userId: session.userId, 15 scopes: session.scopes, 16 organizationId: session.organizationId || "N/A", 17 expiresAt: session.expiresAt.toISOString(), 18 issuedAt: session.issuedAt.toISOString(), 19 }, 20 null, 21 2 22 ); 23 } ``` src/tools/greet.ts ```typescript 1 import { z } from "zod"; 2 import { type InferSchema, type ToolMetadata } from "xmcp"; 3 import { getSession } from "../lib/scalekit-auth"; 4 5 export const schema = { 6 name: z.string().describe("The name to greet"), 7 }; 8 9 export const metadata: ToolMetadata = { 10 name: "greet", 11 description: "Greet the user with their Scalekit identity", 12 }; 13 14 export default function greet({ 15 name, 16 }: InferSchema): string { 17 const session = getSession(); 18 return `Hello, ${name}! Your user ID is ${session.userId}`; 19 } ``` 8. ## Start the server [Section titled “Start the server”](#start-the-server) Terminal ```bash 1 npm run dev ``` You should see: ```plaintext 1 ✔ MCP Server running on http://127.0.0.1:3001/mcp 2 [Scalekit] Resolved JWKS URI: https://.scalekit.com/keys ``` The JWKS log confirms the server successfully connected to Scalekit and can validate tokens. 9. ## Test with MCP Inspector [Section titled “Test with MCP Inspector”](#test-with-mcp-inspector) Verify the full flow using MCP Inspector. Terminal ```bash 1 npx @modelcontextprotocol/inspector@latest ``` In the Inspector UI: 1. Set transport to **Streamable HTTP**, URL to `http://localhost:3001/mcp`, connection to **Direct** 2. Get an access token using client credentials: Terminal ```bash 1 curl -s -X POST "$SCALEKIT_ENVIRONMENT_URL/oauth/token" \ 2 -H "Content-Type: application/x-www-form-urlencoded" \ 3 -d "grant_type=client_credentials\ 4 &client_id=$SCALEKIT_CLIENT_ID\ 5 &client_secret=$SCALEKIT_CLIENT_SECRET" | jq .access_token -r ``` 3. Enable the **Authorization** custom header and set its value to `Bearer ` 4. Click **Connect** — you should see `whoami` and `greet` in the Tools tab You now have a working xmcp MCP server with Scalekit OAuth 2.1 authentication. Add more tools by creating files in `src/tools/`, and access the authenticated user from any tool via `getSession()`. For production deployment, build with `npm run build` and run the compiled output with `npm start`. --- # DOCUMENT BOUNDARY --- # Test users > Set up test users to run automated E2E tests for login and signup flows Test users let you run Playwright, Cypress, and other E2E tests against signup and login flows without waiting for real OTP or magic-link emails. Scalekit accepts a static 6-digit code that you configure, so tests are fast, reliable, and inbox-free. **What doesn’t change:** Test users only affects OTP email delivery. Everything else — organization creation, user creation, session creation, audit logs, webhooks, and post-login redirects — behaves the same as it does for a real user. ### Prerequisites [Section titled “Prerequisites”](#prerequisites) Enable the **Magic Link & OTP** auth method, with the delivery option set to `Verification Code` or `Magic Link + Verification Code`. `Magic Link`-only delivery is not supported. ![Magic link/OTP configuration](/.netlify/images?url=_astro%2F2026-05-14-10-45-39.sA74CAt7.png\&w=2906\&h=1408\&dpl=6aaa70ad2ea7b40008ad2afd) ## Configure test users [Section titled “Configure test users”](#configure-test-users) The test users allowlist is set per environment and accepts up to 5 emails. Configure it once — every signup and login test in that environment uses the same emails and static code. 1. ### Open Test users settings [Section titled “Open Test users settings”](#open-test-users-settings) Go to **Dashboard > Environment settings > Test users**. ![Test users settings page](/.netlify/images?url=_astro%2Ftest-users-settings.zn18KeZw.png\&w=2176\&h=1410\&dpl=6aaa70ad2ea7b40008ad2afd) 2. ### Enable and add emails to the allowlist [Section titled “Enable and add emails to the allowlist”](#enable-and-add-emails-to-the-allowlist) Toggle **Enable test users**. Add up to 5 test emails — emails are stored lowercase and de-duplicated. Each entry must contain `+sktest` in the local part (before `@`); any domain works. | Email | Valid? | Reason | | ----------------------------- | ------ | ------------------------------------- | | `john+sktest@acmecorp.com` | ✓ | `+sktest` present in the local part | | `bob+sktest@anything.example` | ✓ | Any domain works | | `john@acmecorp.com` | ✗ | Missing `+sktest` marker | | `john+test@acmecorp.com` | ✗ | Marker must be exactly `+sktest` | | `sktest+john@acmecorp.com` | ✗ | Must appear after `+`, not before `@` | ![Test users allowlist with an email added](/.netlify/images?url=_astro%2Ftest-users-allowlist.BzUbAWIw.png\&w=2174\&h=1410\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ### Set the static confirmation code [Section titled “Set the static confirmation code”](#set-the-static-confirmation-code) Enter a **Static confirmation code** — exactly 6 digits. The default is `424242`. Tests will enter this code at the OTP prompt. 4. ### Save [Section titled “Save”](#save) Click **Save** and reload the page to confirm the settings persisted. ## Test the signup flow [Section titled “Test the signup flow”](#test-the-signup-flow) Use this flow to verify that a new user can complete signup and end up as a member of an organization. Point the test at Scalekit’s authorization endpoint with `prompt=create` so the browser lands directly on the hosted signup screen: Authorization URL (signup) ```sh /oauth/authorize? response_type=code& client_id=& redirect_uri=& scope=openid+profile+email+offline_access& state=& prompt=create ``` After OTP verification, Scalekit redirects to `` with an authorization code. Assert on the callback URL in your test. * Playwright playwright/e2e/signup.spec.ts ```ts 1 import { test, expect } from '@playwright/test' 2 3 const AUTH_URL = process.env.SCALEKIT_TEST_AUTH_URL! 4 const TEST_USER_EMAIL = process.env.SCALEKIT_TEST_USER_EMAIL! 5 const TEST_USER_CODE = process.env.SCALEKIT_TEST_USER_CODE! 6 7 test('OTP signup with test user', async ({ page }) => { 8 await page.goto(AUTH_URL) 9 10 await page.fill('input[name="email"]', TEST_USER_EMAIL) 11 await page.getByRole('button', { name: 'Continue', exact: true }).click() 12 13 await page.locator('[data-scope="pin-input"][data-part="input"]').first().pressSequentially(TEST_USER_CODE) 14 await page.getByRole('button', { name: 'Continue', exact: true }).click() 15 16 // Replace with your app's post-login URL pattern 17 await expect(page).toHaveURL(/dashboard\.sampleapp\.com/) 18 }) ``` * Cypress cypress/e2e/signup.cy.ts ```ts 1 const AUTH_URL = Cypress.env('SCALEKIT_TEST_AUTH_URL') 2 const TEST_USER_EMAIL = Cypress.env('SCALEKIT_TEST_USER_EMAIL') 3 const TEST_USER_CODE = Cypress.env('SCALEKIT_TEST_USER_CODE') 4 5 describe('OTP signup with test user', () => { 6 it('signs up using the static code', () => { 7 cy.visit(AUTH_URL) 8 9 cy.get('input[name="email"]').type(TEST_USER_EMAIL) 10 cy.get('button[type="submit"]').contains('Continue').click() 11 12 cy.get('[data-scope="pin-input"][data-part="input"]').first().type(TEST_USER_CODE) 13 cy.get('button[type="submit"]').contains('Continue').click() 14 15 // Replace with your app's post-login URL pattern 16 cy.url().should('include', 'dashboard.sampleapp.com') 17 }) 18 }) ``` **Verify:** After running the test, check: * A new organization exists with the test user as a member. Verify in **Dashboard > Organizations > Newly created organization > Users**. ![New organization and user created](/.netlify/images?url=_astro%2F2026-05-14-10-37-41.C1uM9642.png\&w=2910\&h=1404\&dpl=6aaa70ad2ea7b40008ad2afd) * **Auth logs** in **Dashboard > Auth logs** show two test-user events: * *Verification email suppressed (test user)* * *OTP verification successful (test user)* ![Auth logs for test users in signup flow](/.netlify/images?url=_astro%2F2026-05-14-10-40-10.D-kzd9Ri.png\&w=2916\&h=1386\&dpl=6aaa70ad2ea7b40008ad2afd) ## Test the login flow [Section titled “Test the login flow”](#test-the-login-flow) Use this flow to verify login for a user that already exists in an organization. The test user must be created before the test runs. Add them manually in **Dashboard > Organizations > Newly created organization > Users > Create user**, or create them programmatically with the Scalekit API or SDK: * Node.js Create test user in an organization ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 3 const scalekit = new ScalekitClient( 4 process.env.SCALEKIT_ENVIRONMENT_URL!, 5 process.env.SCALEKIT_CLIENT_ID!, 6 process.env.SCALEKIT_CLIENT_SECRET! 7 ) 8 9 const { user } = await scalekit.user.createUserAndMembership(orgId, { 10 email: 'john+sktest@acmecorp.com', 11 sendInvitationEmail: false, 12 }) ``` * Python Create test user in an organization ```python 1 import os 2 from scalekit import ScalekitClient 3 from scalekit.v1.users.users_pb2 import CreateUser 4 5 scalekit_client = ScalekitClient( 6 env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], 7 client_id=os.environ["SCALEKIT_CLIENT_ID"], 8 client_secret=os.environ["SCALEKIT_CLIENT_SECRET"] 9 ) 10 11 user_response = scalekit_client.users.create_user_and_membership( 12 org_id, 13 CreateUser(email="john+sktest@acmecorp.com"), 14 send_invitation_email=False, 15 ) ``` * Go Create test user in an organization ```go 1 import usersv1 "github.com/scalekit-inc/scalekit-sdk-go/v2/pkg/grpc/scalekit/v1/users" 2 3 scalekitClient := scalekit.NewScalekitClient( 4 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 5 os.Getenv("SCALEKIT_CLIENT_ID"), 6 os.Getenv("SCALEKIT_CLIENT_SECRET"), 7 ) 8 9 userResp, err := scalekitClient.User().CreateUserAndMembership(ctx, orgID, 10 &usersv1.CreateUser{Email: "john+sktest@acmecorp.com"}, 11 false, 12 ) 13 if err != nil { 14 log.Fatalf("failed to create user: %v", err) 15 } ``` * Java Create test user in an organization ```java 1 import com.scalekit.grpc.scalekit.v1.users.*; 2 3 ScalekitClient scalekitClient = new ScalekitClient( 4 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 5 System.getenv("SCALEKIT_CLIENT_ID"), 6 System.getenv("SCALEKIT_CLIENT_SECRET") 7 ); 8 9 CreateUserAndMembershipRequest request = CreateUserAndMembershipRequest.newBuilder() 10 .setUser(CreateUser.newBuilder().setEmail("john+sktest@acmecorp.com").build()) 11 .setSendInvitationEmail(false) 12 .build(); 13 14 CreateUserAndMembershipResponse userResp = scalekitClient.users() 15 .createUserAndMembership(orgId, request); ``` Make sure the same email is also on the [test users allowlist](#enable-and-add-emails-to-the-allowlist). ### Run the test [Section titled “Run the test”](#run-the-test) Point the test at Scalekit’s authorization endpoint with `prompt=login` so the browser lands directly on the hosted login screen: Authorization URL (login) ```sh /oauth/authorize? response_type=code& client_id=& redirect_uri=& scope=openid+profile+email+offline_access& state=& prompt=login ``` After OTP verification, Scalekit redirects to `` with an authorization code. Assert on the callback URL in your test. * Playwright playwright/e2e/login.spec.ts ```ts 1 import { test, expect } from '@playwright/test' 2 3 const AUTH_URL = process.env.SCALEKIT_TEST_AUTH_URL! 4 const TEST_USER_EMAIL = process.env.SCALEKIT_TEST_USER_EMAIL! 5 const TEST_USER_CODE = process.env.SCALEKIT_TEST_USER_CODE! 6 7 test('OTP login with test user', async ({ page }) => { 8 await page.goto(AUTH_URL) 9 10 await page.fill('input[name="email"]', TEST_USER_EMAIL) 11 await page.getByRole('button', { name: 'Continue', exact: true }).click() 12 13 await page.locator('[data-scope="pin-input"][data-part="input"]').first().pressSequentially(TEST_USER_CODE) 14 await page.getByRole('button', { name: 'Continue', exact: true }).click() 15 16 // Replace with your app's post-login URL pattern 17 await expect(page).toHaveURL(/dashboard\.sampleapp\.com/) 18 }) ``` * Cypress cypress/e2e/login.cy.ts ```ts 1 const AUTH_URL = Cypress.env('SCALEKIT_TEST_AUTH_URL') 2 const TEST_USER_EMAIL = Cypress.env('SCALEKIT_TEST_USER_EMAIL') 3 const TEST_USER_CODE = Cypress.env('SCALEKIT_TEST_USER_CODE') 4 5 describe('OTP login with test user', () => { 6 it('logs in using the static code', () => { 7 cy.visit(AUTH_URL) 8 9 cy.get('input[name="email"]').type(TEST_USER_EMAIL) 10 cy.get('button[type="submit"]').contains('Continue').click() 11 12 cy.get('[data-scope="pin-input"][data-part="input"]').first().type(TEST_USER_CODE) 13 cy.get('button[type="submit"]').contains('Continue').click() 14 15 // Replace with your app's post-login URL pattern 16 cy.url().should('include', 'dashboard.sampleapp.com') 17 }) 18 }) ``` **Verify:** After running the test, check: * **Auth logs** in **Dashboard > Auth logs** show two test-user events: * *Verification email suppressed (test user)* * *OTP verification successful (test user)* ![Auth log showing test-user events](/.netlify/images?url=_astro%2Ftest-users-auth-log.DqWyyLRk.png\&w=2916\&h=1388\&dpl=6aaa70ad2ea7b40008ad2afd) ## Production safety [Section titled “Production safety”](#production-safety) Test Users bypass real email verification Keep Test Users off in production environments unless you have a deliberate reason to enable it. When it is on, a warning banner appears in the dashboard. ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) --- # DOCUMENT BOUNDARY --- # Add Modular SSO > Enable enterprise SSO for any customer in minutes with built-in SAML and OIDC integrations Enterprise customers often require Single Sign-On (SSO) support for their applications. Rather than building custom integrations for every identity provider—such as Okta, Entra ID, or JumpCloud—and managing the detailed configuration of OIDC and SAML protocols, there are more scalable approaches available. Modular SSO is designed for applications that maintain their own user database and session management. This lightweight integration focuses solely on identity verification, giving you complete control over user data and authentication flows. Choose Modular SSO when you: * Want to manage user records in your own database * Prefer to implement custom session management logic * Need to integrate SSO without changing your existing authentication architecture * Already have existing user management infrastructure Using a coding agent?Copy SSO prompt 1. ## Configure “Modular Auth” mode [Section titled “Configure “Modular Auth” mode”](#configure-modular-auth-mode) Ensure your environment is configured in Modular Auth mode. 1. Go to Dashboard > Settings > Authentication Mode 2. Select “Modular Auth” and save Now you’re ready to start integrating SSO into your app! Next, we’ll cover how to use the SDK to authenticate users. 2. ## Set up Scalekit [Section titled “Set up Scalekit”](#set-up-scalekit) Use the following instructions to install the SDK for your technology stack. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Configure your environment with API credentials. Navigate to **Dashboard > Developers > Settings > API credentials** and copy these values to your `.env` file: .env ```sh SCALEKIT_ENVIRONMENT_URL= # Example: https://acme.scalekit.dev or https://auth.acme.com (if custom domain is set) SCALEKIT_CLIENT_ID= # Example: skc_1234567890abcdef SCALEKIT_CLIENT_SECRET= # Example: test_abcdef1234567890 ``` ### Register redirect URL for your app [Section titled “Register redirect URL for your app”](#register-redirect-url-for-your-app) You need to register redirect URL for your application. Go to **Scalekit dashboard** → **Authentication** → **Redirect URLs** and configure: * **Allowed callback URLs**: The endpoint where users are sent after successful authentication to exchange authorization codes and retrieve profile information. [Learn more](/guides/dashboard/redirects/#allowed-callback-urls) * **Initiate login URL**: The endpoint in your app that redirects users to Scalekit’s `/authorize` endpoint. Required when user starts sign-in directly from their identity provider (IdP-initiated SSO). [Learn more](/guides/dashboard/redirects/#initiate-login-url) 3. ## Redirect the users to their enterprise identity provider login page [Section titled “Redirect the users to their enterprise identity provider login page”](#redirect-the-users-to-their-enterprise-identity-provider-login-page) Create an authorization URL to redirect users to Scalekit’s sign-in page. Use the Scalekit SDK to construct this URL with your redirect URI and required scopes. * Node.js authorization-url.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new ScalekitClient( 4 '', // Your Scalekit environment URL 5 '', // Unique identifier for your app 6 '', 7 ); 8 9 const options = {}; 10 11 // Specify which SSO connection to use (choose one based on your use case) 12 // These identifiers are evaluated in order of precedence: 13 14 // 1. connectionId (highest precedence) - Use when you know the exact SSO connection 15 options['connectionId'] = 'conn_15696105471768821'; 16 17 // 2. organizationId - Routes to organization's SSO (useful for multi-tenant apps) 18 // If org has multiple connections, the first active one is selected 19 options['organizationId'] = 'org_15421144869927830'; 20 21 // 3. loginHint (lowest precedence) - Extracts domain from email to find connection 22 // Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 23 options['loginHint'] = 'user@example.com'; 24 25 // redirect_uri: Your callback endpoint that receives the authorization code 26 // Must match the URL registered in your Scalekit dashboard 27 const redirectUrl = 'https://your-app.com/auth/callback'; 28 29 const authorizationURL = scalekit.getAuthorizationUrl(redirectUrl, options); 30 // Redirect user to this URL to begin SSO authentication ``` * Python authorization\_url.py ```python 1 from scalekit import ScalekitClient, AuthorizationUrlOptions 2 3 scalekit = ScalekitClient( 4 '', # Your Scalekit environment URL 5 '', # Unique identifier for your app 6 '' 7 ) 8 9 options = AuthorizationUrlOptions() 10 11 # Specify which SSO connection to use (choose one based on your use case) 12 # These identifiers are evaluated in order of precedence: 13 14 # 1. connection_id (highest precedence) - Use when you know the exact SSO connection 15 options.connection_id = 'conn_15696105471768821' 16 17 # 2. organization_id - Routes to organization's SSO (useful for multi-tenant apps) 18 # If org has multiple connections, the first active one is selected 19 options.organization_id = 'org_15421144869927830' 20 21 # 3. login_hint (lowest precedence) - Extracts domain from email to find connection 22 # Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 23 options.login_hint = 'user@example.com' 24 25 # redirect_uri: Your callback endpoint that receives the authorization code 26 # Must match the URL registered in your Scalekit dashboard 27 redirect_uri = 'https://your-app.com/auth/callback' 28 29 authorization_url = scalekit_client.get_authorization_url( 30 redirect_uri=redirect_uri, 31 options=options 32 ) 33 # Redirect user to this URL to begin SSO authentication ``` * Go authorization\_url.go ```go 1 import ( 2 "github.com/scalekit-inc/scalekit-sdk-go" 3 ) 4 5 func main() { 6 scalekitClient := scalekit.NewScalekitClient( 7 "", // Your Scalekit environment URL 8 "", // Unique identifier for your app 9 "" 10 ) 11 12 options := scalekitClient.AuthorizationUrlOptions{} 13 14 // Specify which SSO connection to use (choose one based on your use case) 15 // These identifiers are evaluated in order of precedence: 16 17 // 1. ConnectionId (highest precedence) - Use when you know the exact SSO connection 18 options.ConnectionId = "conn_15696105471768821" 19 20 // 2. OrganizationId - Routes to organization's SSO (useful for multi-tenant apps) 21 // If org has multiple connections, the first active one is selected 22 options.OrganizationId = "org_15421144869927830" 23 24 // 3. LoginHint (lowest precedence) - Extracts domain from email to find connection 25 // Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 26 options.LoginHint = "user@example.com" 27 28 // redirectUrl: Your callback endpoint that receives the authorization code 29 // Must match the URL registered in your Scalekit dashboard 30 redirectUrl := "https://your-app.com/auth/callback" 31 32 authorizationURL := scalekitClient.GetAuthorizationUrl( 33 redirectUrl, 34 options, 35 ) 36 // Redirect user to this URL to begin SSO authentication 37 } ``` * Java AuthorizationUrl.java ```java 1 package com.scalekit; 2 3 import com.scalekit.ScalekitClient; 4 import com.scalekit.internal.http.AuthorizationUrlOptions; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 ScalekitClient scalekitClient = new ScalekitClient( 10 "", // Your Scalekit environment URL 11 "", // Unique identifier for your app 12 "" 13 ); 14 15 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 16 17 // Specify which SSO connection to use (choose one based on your use case) 18 // These identifiers are evaluated in order of precedence: 19 20 // 1. connectionId (highest precedence) - Use when you know the exact SSO connection 21 options.setConnectionId("con_13388706786312310"); 22 23 // 2. organizationId - Routes to organization's SSO (useful for multi-tenant apps) 24 // If org has multiple connections, the first active one is selected 25 options.setOrganizationId("org_13388706786312310"); 26 27 // 3. loginHint (lowest precedence) - Extracts domain from email to find connection 28 // Domain must be registered to the organization (manually via Dashboard or through admin portal during enterprise onboarding) 29 options.setLoginHint("user@example.com"); 30 31 // redirectUrl: Your callback endpoint that receives the authorization code 32 // Must match the URL registered in your Scalekit dashboard 33 String redirectUrl = "https://your-app.com/auth/callback"; 34 35 try { 36 String url = scalekitClient 37 .authentication() 38 .getAuthorizationUrl(redirectUrl, options) 39 .toString(); 40 // Redirect user to this URL to begin SSO authentication 41 } catch (Exception e) { 42 System.out.println(e.getMessage()); 43 } 44 } 45 } ``` * Direct URL (No SDK) OAuth2 authorization URL ```sh /oauth/authorize? response_type=code& # OAuth2 authorization code flow client_id=& # Your Scalekit client ID redirect_uri=& # URL-encoded callback URL scope=openid profile email& # Note: "offline_access" scope is not supported in Modular SSO organization_id=org_15421144869927830& # (Optional) Route by organization connection_id=conn_15696105471768821& # (Optional) Specific SSO connection login_hint=user@example.com # (Optional) Extract domain from email ``` **SSO identifiers** (choose one or more, evaluated in order of precedence): * `connection_id` - Direct to specific SSO connection (highest precedence) * `organization_id` - Route to organization’s SSO * `domain_hint` - Lookup connection by domain * `login_hint` - Extract domain from email (lowest precedence). Domain must be registered to the organization (manually via Dashboard or through admin portal when [onboarding an enterprise customer](/sso/guides/onboard-enterprise-customers/)) Example with actual values ```http https://tinotat-dev.scalekit.dev/oauth/authorize? response_type=code& client_id=skc_88036702639096097& redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback& scope=openid%20profile%20email& organization_id=org_15421144869927830 ``` Enterprise users see their identity provider’s login page. Users verify their identity through the authentication policies set by their organization’s administrator. Post successful verification, the user profile is [normalized](/sso/guides/user-profile-details/) and sent to your app. For details on how Scalekit determines which SSO connection to use, refer to the [SSO identifier precedence rules](/sso/guides/authorization-url/#parameter-precedence). 4. ## Handle IdP-initiated SSO Recommended [Section titled “Handle IdP-initiated SSO ”](#handle-idp-initiated-sso-) When users start the login process from their identity provider’s portal (rather than your application), this is called IdP-initiated SSO. Scalekit converts these requests to secure SP-initiated flows automatically. Your initiate login endpoint receives an `idp_initiated_login` JWT parameter containing the user’s organization and connection details. Decode this token and generate a new authorization URL to complete the authentication flow securely. ```sh https://yourapp.com/login?idp_initiated_login= ``` Configure your initiate login endpoint in [Dashboard > Authentication > Redirects](/guides/dashboard/redirects/#initiate-login-url) * Node.js handle-idp-initiated.js ```javascript 1 // Your initiate login endpoint receives the IdP-initiated login token 2 const { idp_initiated_login, error, error_description } = req.query; 3 4 if (error) { 5 return res.status(400).json({ message: error_description }); 6 } 7 8 // When users start login from their IdP portal, convert to SP-initiated flow 9 if (idp_initiated_login) { 10 // Decode the JWT to extract organization and connection information 11 const claims = await scalekit.getIdpInitiatedLoginClaims(idp_initiated_login); 12 13 const options = { 14 connectionId: claims.connection_id, // Specific SSO connection 15 organizationId: claims.organization_id, // User's organization 16 loginHint: claims.login_hint, // User's email for context 17 state: claims.relay_state // Preserve state from IdP 18 }; 19 20 // Generate authorization URL and redirect to complete authentication 21 const authorizationURL = scalekit.getAuthorizationUrl( 22 'https://your-app.com/auth/callback', 23 options 24 ); 25 26 return res.redirect(authorizationURL); 27 } ``` * Python handle\_idp\_initiated.py ```python 1 # Your initiate login endpoint receives the IdP-initiated login token 2 idp_initiated_login = request.args.get('idp_initiated_login') 3 error = request.args.get('error') 4 error_description = request.args.get('error_description') 5 6 if error: 7 raise Exception(error_description) 8 9 # When users start login from their IdP portal, convert to SP-initiated flow 10 if idp_initiated_login: 11 # Decode the JWT to extract organization and connection information 12 claims = await scalekit.get_idp_initiated_login_claims(idp_initiated_login) 13 14 options = AuthorizationUrlOptions() 15 options.connection_id = claims.get('connection_id') # Specific SSO connection 16 options.organization_id = claims.get('organization_id') # User's organization 17 options.login_hint = claims.get('login_hint') # User's email for context 18 options.state = claims.get('relay_state') # Preserve state from IdP 19 20 # Generate authorization URL and redirect to complete authentication 21 authorization_url = scalekit.get_authorization_url( 22 redirect_uri='https://your-app.com/auth/callback', 23 options=options 24 ) 25 26 return redirect(authorization_url) ``` * Go handle\_idp\_initiated.go ```go 1 // Your initiate login endpoint receives the IdP-initiated login token 2 idpInitiatedLogin := r.URL.Query().Get("idp_initiated_login") 3 errorDesc := r.URL.Query().Get("error_description") 4 5 if errorDesc != "" { 6 http.Error(w, errorDesc, http.StatusBadRequest) 7 return 8 } 9 10 // When users start login from their IdP portal, convert to SP-initiated flow 11 if idpInitiatedLogin != "" { 12 // Decode the JWT to extract organization and connection information 13 claims, err := scalekitClient.GetIdpInitiatedLoginClaims(r.Context(), idpInitiatedLogin) 14 if err != nil { 15 http.Error(w, err.Error(), http.StatusInternalServerError) 16 return 17 } 18 19 options := scalekit.AuthorizationUrlOptions{ 20 ConnectionId: claims.ConnectionID, // Specific SSO connection 21 OrganizationId: claims.OrganizationID, // User's organization 22 LoginHint: claims.LoginHint, // User's email for context 23 } 24 25 // Generate authorization URL and redirect to complete authentication 26 authUrl, err := scalekitClient.GetAuthorizationUrl( 27 "https://your-app.com/auth/callback", 28 options 29 ) 30 31 if err != nil { 32 http.Error(w, err.Error(), http.StatusInternalServerError) 33 return 34 } 35 36 http.Redirect(w, r, authUrl.String(), http.StatusFound) 37 } ``` * Java HandleIdpInitiated.java ```java 1 // Your initiate login endpoint receives the IdP-initiated login token 2 @GetMapping("/login") 3 public RedirectView handleInitiateLogin( 4 @RequestParam(required = false, name = "idp_initiated_login") String idpInitiatedLoginToken, 5 @RequestParam(required = false) String error, 6 @RequestParam(required = false, name = "error_description") String errorDescription, 7 HttpServletResponse response) throws IOException { 8 9 if (error != null) { 10 response.sendError(HttpStatus.BAD_REQUEST.value(), errorDescription); 11 return null; 12 } 13 14 // When users start login from their IdP portal, convert to SP-initiated flow 15 if (idpInitiatedLoginToken != null) { 16 // Decode the JWT to extract organization and connection information 17 IdpInitiatedLoginClaims claims = scalekit 18 .authentication() 19 .getIdpInitiatedLoginClaims(idpInitiatedLoginToken); 20 21 if (claims == null) { 22 response.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid token"); 23 return null; 24 } 25 26 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 27 options.setConnectionId(claims.getConnectionID()); // Specific SSO connection 28 options.setOrganizationId(claims.getOrganizationID()); // User's organization 29 options.setLoginHint(claims.getLoginHint()); // User's email for context 30 31 // Generate authorization URL and redirect to complete authentication 32 String authUrl = scalekit 33 .authentication() 34 .getAuthorizationUrl("https://your-app.com/auth/callback", options) 35 .toString(); 36 37 response.sendRedirect(authUrl); 38 return null; 39 } 40 41 return null; 42 } ``` This approach provides enhanced security by converting IdP-initiated requests to standard SP-initiated flows, protecting against SAML assertion theft and replay attacks. Learn more: [IdP-initiated SSO implementation guide](/sso/guides/idp-init-sso/) 5. ## Get user details from the callback [Section titled “Get user details from the callback”](#get-user-details-from-the-callback) After successful authentication, Scalekit redirects to your callback URL with an authorization code. Your application exchanges this code for the user’s profile information and session tokens. 1. Add a callback endpoint in your application (typically `https://your-app.com/auth/callback`) 2. [Register](/guides/dashboard/redirects/#allowed-callback-urls) it in your Scalekit dashboard > Authentication > Redirect URLS > Allowed Callback URLs In authentication flow, Scalekit redirects to your callback URL with an authorization code. Your application exchanges this code for the user’s profile information. * Node.js Fetch user profile ```javascript 1 // Extract authentication parameters from the callback request 2 const { 3 code, 4 error, 5 error_description, 6 idp_initiated_login, 7 connection_id, 8 relay_state 9 } = req.query; 10 11 if (error) { 12 // Handle authentication errors returned from the identity provider 13 } 14 15 // Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 16 17 const result = await scalekit.authenticateWithCode(code, redirectUri); 18 const userEmail = result.user.email; 19 20 // Create a session for the authenticated user and grant appropriate access permissions ``` * Python Fetch user profile ```py 1 # Extract authentication parameters from the callback request 2 code = request.args.get('code') 3 error = request.args.get('error') 4 error_description = request.args.get('error_description') 5 idp_initiated_login = request.args.get('idp_initiated_login') 6 connection_id = request.args.get('connection_id') 7 relay_state = request.args.get('relay_state') 8 9 if error: 10 raise Exception(error_description) 11 12 # Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 13 14 result = scalekit.authenticate_with_code(code, '') 15 16 # Access normalized user profile information 17 user_email = result.user.email 18 19 # Create a session for the authenticated user and grant appropriate access permissions ``` * Go Fetch user profile ```go 1 // Extract authentication parameters from the callback request 2 code := r.URL.Query().Get("code") 3 error := r.URL.Query().Get("error") 4 errorDescription := r.URL.Query().Get("error_description") 5 idpInitiatedLogin := r.URL.Query().Get("idp_initiated_login") 6 connectionID := r.URL.Query().Get("connection_id") 7 relayState := r.URL.Query().Get("relay_state") 8 9 if error != "" { 10 // Handle authentication errors returned from the identity provider 11 } 12 13 // Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 14 15 result, err := scalekitClient.AuthenticateWithCode(r.Context(), code, redirectUrl) 16 17 if err != nil { 18 // Handle token exchange or validation errors 19 } 20 21 // Access normalized user profile information 22 userEmail := result.User.Email 23 24 // Create a session for the authenticated user and grant appropriate access permissions ``` * Java Fetch user profile ```java 1 // Extract authentication parameters from the callback request 2 String code = request.getParameter("code"); 3 String error = request.getParameter("error"); 4 String errorDescription = request.getParameter("error_description"); 5 String idpInitiatedLogin = request.getParameter("idp_initiated_login"); 6 String connectionID = request.getParameter("connection_id"); 7 String relayState = request.getParameter("relay_state"); 8 9 if (error != null && !error.isEmpty()) { 10 // Handle authentication errors returned from the identity provider 11 return; 12 } 13 14 // Recommended: Process IdP-initiated login flows (when users start from their SSO portal) 15 16 try { 17 AuthenticationResponse result = scalekit.authentication().authenticateWithCode(code, redirectUrl); 18 String userEmail = result.getIdTokenClaims().getEmail(); 19 20 // Create a session for the authenticated user and grant appropriate access permissions 21 } catch (Exception e) { 22 // Handle token exchange or validation errors 23 } ``` The `result` object * Node.js Validate tokens ```js 1 // Validate and decode the ID token from the authentication result 2 const idTokenClaims = await scalekit.validateToken(result.idToken); 3 4 // Validate and decode the access token 5 const accessTokenClaims = await scalekit.validateToken(result.accessToken); ``` * Python Validate tokens ```py 1 # Validate and decode the ID token from the authentication result 2 id_token_claims = scalekit_client.validate_token(result["id_token"]) 3 4 # Validate and decode the access token 5 access_token_claims = scalekit_client.validate_token(result["access_token"]) ``` * Go Validate tokens ```go 1 // Validate and decode the access token (uses JWKS from the client) 2 accessTokenClaims, err := scalekitClient.GetAccessTokenClaims(ctx, result.AccessToken) 3 if err != nil { 4 // handle error 5 } ``` * Java Validate tokens ```java 1 // Validate and decode the ID token 2 Map idTokenClaims = scalekitClient.validateToken(result.getIdToken()); 3 4 // Validate and decode the access token 5 Map accessTokenClaims = scalekitClient.validateToken(result.getAccessToken()); ``` - Auth result ```js 1 { 2 user: { 3 email: 'john@example.com', 4 familyName: 'Doe', 5 givenName: 'John', 6 username: 'john@example.com', 7 id: 'conn_70087756662964366;dcc62570-6a5a-4819-b11b-d33d110c7716' 8 }, 9 idToken: 'eyJhbGciOiJSU..bcLQ', 10 accessToken: 'eyJhbGciO..', 11 expiresIn: 899 12 } ``` - ID token (decoded) ```js 1 { 2 amr: [ 'conn_70087756662964366' ], // SSO connection ID 3 at_hash: 'yMGIBg7BkmIGgD6_dZPEGQ', 4 aud: [ 'skc_70087756327420046' ], 5 azp: 'skc_70087756327420046', 6 c_hash: '4x7qsXnlRw6dRC6twnuENw', 7 client_id: 'skc_70087756327420046', 8 email: 'john@example.com', 9 exp: 1758952038, 10 family_name: 'Doe', 11 given_name: 'John', 12 iat: 1758692838, 13 iss: '', 14 oid: 'org_70087756646187150', 15 preferred_username: 'john@example.com', 16 sid: 'ses_91646612652163629', 17 sub: 'conn_70087756662964366;e964d135-35c7-4a13-a3b4-2579a1cdf4e6' 18 } ``` - Access token (decoded) ```js 1 { 2 "iss": "", 3 "sub": "conn_70087756662964366;dcc62570-6a5a-4819-b11b-d33d110c7716", 4 "aud": [ 5 "skc_70087756327420046" 6 ], 7 "exp": 1758693916, 8 "iat": 1758693016, 9 "nbf": 1758693016, 10 "client_id": "skc_70087756327420046", 11 "jti": "tkn_91646913048216109" 12 } ``` 6. ## Test your SSO integration [Section titled “Test your SSO integration”](#test-your-sso-integration) Validate your implementation using the **IdP Simulator** and **Test Organization** included in your development environment. Test all three scenarios before deploying to production. Your environment includes a pre-configured test organization (found in **Dashboard > Organizations**) with domains like `@example.com` and `@example.org` for testing. Pass one of the following connection selectors in your authorization URL: * Email address with `@example.com` or `@example.org` domain * Test organization’s connection ID * Organization ID This opens the SSO login page (IdP Simulator) that simulates your customer’s identity provider login experience. ![IdP Simulator](/.netlify/images?url=_astro%2F2.1.BEM1Vo-J.png\&w=2646\&h=1652\&dpl=6aaa70ad2ea7b40008ad2afd) For detailed testing instructions and scenarios, see our [Complete SSO testing guide](/sso/guides/test-sso/) 7. ## Set up SSO with your existing authentication system [Section titled “Set up SSO with your existing authentication system”](#set-up-sso-with-your-existing-authentication-system) Many applications already use an authentication provider such as Auth0, Firebase, or AWS Cognito. To enable single sign-on (SSO) using Scalekit, configure Scalekit to work with your current authentication provider. ### Auth0 Integrate Scalekit with Auth0 for enterprise SSO [Know more →](/guides/integrations/auth-systems/auth0) ### Firebase Auth Add enterprise authentication to Firebase projects [Know more →](/guides/integrations/auth-systems/firebase) ### AWS Cognito Configure Scalekit with AWS Cognito user pools [Know more →](/guides/integrations/auth-systems/aws-cognito) 8. ## Onboard enterprise customers [Section titled “Onboard enterprise customers”](#onboard-enterprise-customers) Enable SSO for your enterprise customers by creating an organization in Scalekit and providing them access to the Admin Portal. Your customers configure their identity provider settings themselves through a self-service portal. **Create an organization** for your customer in [Dashboard > Organizations](https://app.scalekit.com/organizations), then provide Admin Portal access using one of these methods: * Shareable link Generate a secure link your customer can use to access the Admin Portal: generate-portal-link.js ```javascript // Generate a one-time Admin Portal link for your customer const portalLink = await scalekit.organization.generatePortalLink( 'org_32656XXXXXX0438' // Your customer's organization ID ); // Share this link with your customer's IT admin via email or messaging // Example: '/magicLink/8930509d-68cf-4e2c-8c6d-94d2b5e2db43 console.log('Admin Portal URL:', portalLink.location); ``` Send this link to your customer’s IT administrator through email, Slack, or your preferred communication channel. They can configure their SSO connection without any developer involvement. * Embedded portal Embed the Admin Portal directly in your application using an iframe: embed-portal.js ```javascript // Generate a secure portal link at runtime const portalLink = await scalekit.organization.generatePortalLink(orgId); // Return the link to your frontend to embed in an iframe res.json({ portalUrl: portalLink.location }); ``` admin-settings.html ```html ``` Customers configure SSO without leaving your application, maintaining a consistent user experience. Listen for UI events from the embedded portal to respond to configuration changes, such as when SSO is enabled or the session expires. See the [Admin portal UI events reference](/reference/admin-portal/ui-events/) for details on handling these events. Learn more: [Embedded Admin Portal guide](/guides/admin-portal/#embed-the-admin-portal) **Enable domain verification** for seamless user experience. Once your customer verifies their domain (e.g., `@megacorp.org`), users can sign in without selecting their organization. Scalekit automatically routes them to the correct identity provider based on their email domain. **Pre-check SSO availability** before redirecting users. This prevents failed redirects when a user’s domain doesn’t have SSO configured: * Node.js check-sso-availability.js ```javascript 1 // Extract domain from user's email address 2 const domain = email.split('@')[1].toLowerCase(); // e.g., "megacorp.org" 3 4 // Check if domain has an active SSO connection 5 const { connections } = await scalekit.connection.listConnectionsByDomain(domain); 6 7 if (connections.length > 0) { 8 // Domain has SSO configured - redirect to identity provider 9 const authUrl = scalekit.getAuthorizationUrl(redirectUri, { 10 domainHint: domain // Automatically routes to correct IdP 11 }); 12 return res.redirect(authUrl); 13 } else { 14 // No SSO for this domain - show alternative login methods 15 return showPasswordlessLogin(); 16 } ``` * Python check\_sso\_availability.py ```python 1 # Extract domain from user's email address 2 domain = email.split('@')[1].lower() # e.g., "megacorp.org" 3 4 # Check if domain has an active SSO connection 5 connections = scalekit_client.connection.list_connections_by_domain(domain=domain).connections 6 7 if len(connections) > 0: 8 # Domain has SSO configured - redirect to identity provider 9 options = AuthorizationUrlOptions() 10 options.domain_hint = domain # Automatically routes to correct IdP 11 12 auth_url = scalekit_client.get_authorization_url( 13 redirect_uri=redirect_uri, 14 options=options 15 ) 16 return redirect(auth_url) 17 else: 18 # No SSO for this domain - show alternative login methods 19 return show_passwordless_login() ``` * Go check\_sso\_availability.go ```go 1 // Extract domain from user's email address 2 parts := strings.Split(email, "@") 3 domain := strings.ToLower(parts[1]) // e.g., "megacorp.org" 4 5 // Check if domain has an active SSO connection 6 connections, err := scalekitClient.Connections.ListConnectionsByDomain(domain) 7 if err != nil { 8 // Handle error 9 return err 10 } 11 12 if len(connections) > 0 { 13 // Domain has SSO configured - redirect to identity provider 14 options := scalekit.AuthorizationUrlOptions{ 15 DomainHint: domain, // Automatically routes to correct IdP 16 } 17 18 authUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options) 19 if err != nil { 20 return err 21 } 22 23 c.Redirect(http.StatusFound, authUrl.String()) 24 } else { 25 // No SSO for this domain - show alternative login methods 26 return showPasswordlessLogin() 27 } ``` * Java CheckSsoAvailability.java ```java 1 // Extract domain from user's email address 2 String[] parts = email.split("@"); 3 String domain = parts[1].toLowerCase(); // e.g., "megacorp.org" 4 5 // Check if domain has an active SSO connection 6 List connections = scalekitClient 7 .connections() 8 .listConnectionsByDomain(domain); 9 10 if (connections.size() > 0) { 11 // Domain has SSO configured - redirect to identity provider 12 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 13 options.setDomainHint(domain); // Automatically routes to correct IdP 14 15 String authUrl = scalekitClient 16 .authentication() 17 .getAuthorizationUrl(redirectUri, options) 18 .toString(); 19 20 return new RedirectView(authUrl); 21 } else { 22 // No SSO for this domain - show alternative login methods 23 return showPasswordlessLogin(); 24 } ``` This check ensures users only see SSO options when available, improving the login experience and reducing confusion. --- # DOCUMENT BOUNDARY --- # Admin portal > Implement Scalekit's self-serve admin portal to let customers configure SSO via a shareable link or embedded iframe The admin portal provides a self-serve interface for customers to configure single sign-on (SSO) and directory sync (SCIM) connections. Scalekit hosts the portal and provides two integration methods: generate a shareable link through the dashboard or programmatically embed the portal in your application using an iframe. This guide shows you how to implement both integration methods. For the broader customer onboarding workflow, see [Onboard enterprise customers](/sso/guides/onboard-enterprise-customers/). ## Generate shareable portal link No-code Generate a shareable link through the Scalekit dashboard to give customers access to the admin portal. This method requires no code and is ideal for quick setup. ### Create the portal link 1. Log in to the [Scalekit dashboard](https://app.scalekit.com) 2. Navigate to **Dashboard > Organizations** 3. Select the target organization 4. Click **Generate link** to create a shareable admin portal link The generated link follows this format: Portal link example ```http https://your-app.scalekit.dev/magicLink/2cbe56de-eec4-41d2-abed-90a5b82286c4_p ``` ### Link properties | Property | Details | | -------------- | ------------------------------------------------------------------------------- | | **Expiration** | Links expire after 7 days | | **Revocation** | Revoke links anytime from the dashboard | | **Sharing** | Share via email, Slack, or any preferred channel | | **Security** | Anyone with the link can view and update the organization’s connection settings | Security consideration Treat portal links as sensitive credentials. Anyone with the link can view and modify the organization’s SSO and SCIM configuration. ## Embed the admin portal Programmatic Embed the admin portal directly in your application using an iframe. This allows customers to configure SSO and SCIM without leaving your app, creating a seamless experience within your settings or admin interface. The portal link must be generated programmatically on each page load for security. Each generated link is single-use and expires after 1 minute, though once loaded, the session remains active for up to 6 hours. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` ### Generate portal link Use the Scalekit SDK to generate a unique, embeddable admin portal link for an organization. Call this API endpoint each time you render the page containing the iframe. * Node.js Express.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new Scalekit( 4 process.env.SCALEKIT_ENVIRONMENT_URL, 5 process.env.SCALEKIT_CLIENT_ID, 6 process.env.SCALEKIT_CLIENT_SECRET, 7 ); 8 9 async function generatePortalLink(organizationId) { 10 const link = await scalekit.organization.generatePortalLink(organizationId); 11 return link.location; // Use as iframe src 12 } ``` * Python Flask ```python 1 from scalekit import Scalekit 2 import os 3 4 scalekit_client = Scalekit( 5 environment_url=os.environ.get("SCALEKIT_ENVIRONMENT_URL"), 6 client_id=os.environ.get("SCALEKIT_CLIENT_ID"), 7 client_secret=os.environ.get("SCALEKIT_CLIENT_SECRET") 8 ) 9 10 def generate_portal_link(organization_id): 11 link = scalekit_client.organization.generate_portal_link(organization_id) 12 return link.location # Use as iframe src ``` * Go Gin ```go 1 import ( 2 "context" 3 "os" 4 5 "github.com/scalekit/sdk-go" 6 ) 7 8 scalekitClient := scalekit.New( 9 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 10 os.Getenv("SCALEKIT_CLIENT_ID"), 11 os.Getenv("SCALEKIT_CLIENT_SECRET"), 12 ) 13 14 func generatePortalLink(organizationID string) (string, error) { 15 ctx := context.Background() 16 link, err := scalekitClient.Organization().GeneratePortalLink(ctx, organizationID) 17 if err != nil { 18 return "", err 19 } 20 return link.Location, nil // Use as iframe src 21 } ``` * Java Spring Boot ```java 1 import com.scalekit.client.Scalekit; 2 import com.scalekit.client.models.Link; 3 import com.scalekit.client.models.Feature; 4 import java.util.Arrays; 5 6 Scalekit scalekitClient = new Scalekit( 7 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 8 System.getenv("SCALEKIT_CLIENT_ID"), 9 System.getenv("SCALEKIT_CLIENT_SECRET") 10 ); 11 12 public String generatePortalLink(String organizationId) { 13 Link portalLink = scalekitClient.organizations() 14 .generatePortalLink(organizationId, Arrays.asList(Feature.sso, Feature.dir_sync, Feature.domain_verification)); 15 return portalLink.getLocation(); // Use as iframe src 16 } ``` The API returns a JSON object with the portal link. Use the `location` property as the iframe `src`: API response ```json { "id": "8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "location": "https://random-subdomain.scalekit.dev/magicLink/8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "expireTime": "2024-10-03T13:35:50.563013Z" } ``` Embed portal in iframe ```html ``` Embed the portal in your application’s settings or admin section where customers manage authentication configuration. ### Configuration and session | Setting | Requirement | | --------------------- | ----------------------------------------------------------------------------------------------------- | | **Redirect URI** | Add your application domain at **Dashboard > Authentication > Redirect URLs > Allowed callback URLs** | | **iframe attributes** | Include `allow="clipboard-write"` for copy-paste functionality | | **Dimensions** | Minimum recommended height: 600px | | **Link expiration** | Generated links expire after 1 minute if not loaded | | **Session duration** | Portal session remains active for up to 6 hours once loaded | | **Single-use** | Each generated link can only be used once to initialize a session | ## Customize the admin portal Match the admin portal to your brand identity. Configure branding at **Dashboard > Settings > Branding**: | Option | Description | | ---------------- | --------------------------------------------------------- | | **Logo** | Upload your company logo (displayed in the portal header) | | **Accent color** | Set the primary color to match your brand palette | | **Favicon** | Provide a custom favicon for browser tabs | For additional customization options including custom domains, see the [Custom domain guide](/guides/custom-domain/). [SSO integrations](/guides/integrations/sso-integrations/)Administrator guides to set up SSO integrations [Portal events](/reference/admin-portal/ui-events/)Listen to the browser events emitted from the embedded admin portal --- # DOCUMENT BOUNDARY --- # Enterprise SSO code samples > Code samples demonstrating Single Sign-On implementations with Express.js, PHP Symfony, .NET Core, Firebase, AWS Cognito, and Next.js ### [Add SSO to Express.js apps](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/sso-express-example) [Implement Scalekit SSO in a Node.js Express application. Includes middleware setup for secure session handling](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/sso-express-example) ### [Add SSO to PHP Symfony apps](https://github.com/scalekit-developers/scalekit-php-symfony-sso) [Call Scalekit OIDC endpoints from Symfony with no PHP SDK. Try handshake-only login or Modular SSO with a local user store](https://github.com/scalekit-developers/scalekit-php-symfony-sso) ### [Add SSO to .NET Core apps](https://github.com/scalekit-inc/dotnet-example-apps) [Secure .NET Core applications with Scalekit SSO. Demonstrates authentication pipelines and user claims management](https://github.com/scalekit-inc/dotnet-example-apps) ### [Add SSO to Spring Boot apps](https://github.com/scalekit-developers/scalekit-springboot-example) [Integrate Scalekit SSO with Spring Security. Shows how to configure security filters and protect Java endpoints](https://github.com/scalekit-developers/scalekit-springboot-example) ### [Add SSO to Python FastAPI](https://github.com/scalekit-developers/scalekit-fastapi-example) [Add enterprise SSO to FastAPI services using Scalekit. Includes async route protection and user session validation](https://github.com/scalekit-developers/scalekit-fastapi-example) ### [Add SSO to Go applications](https://github.com/scalekit-developers/scalekit-go-example) [Implement Scalekit SSO in Go. Features idiomatically written middleware for securing HTTP handlers](https://github.com/scalekit-developers/scalekit-go-example) ### [Add SSO to Next.js apps](https://github.com/scalekit-developers/scalekit-nextjs-demo) [Secure Next.js applications with Scalekit. Covers both App Router and Pages Router authentication patterns](https://github.com/scalekit-developers/scalekit-nextjs-demo) ### Scalekit SSO + Your own auth system ### [Connect Firebase Auth with SSO](https://github.com/scalekit-inc/scalekit-firebase-sso) [Enable Enterprise SSO for Firebase apps using Scalekit. Learn to link Scalekit identities with Firebase Authentication](https://github.com/scalekit-inc/scalekit-firebase-sso) ### [Connect AWS Cognito with SSO](https://github.com/scalekit-inc/scalekit-cognito-sso) [Add Enterprise SSO to Cognito user pools via Scalekit. Step-by-step guide to federating identity providers](https://github.com/scalekit-inc/scalekit-cognito-sso) ### [Cognito + Scalekit for Next.js](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/cognito-scalekit) [Integrate Cognito and Scalekit SSO in Next.js. Uses OIDC protocols to secure your full-stack React application](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/cognito-scalekit) ## Admin portal ### [Embed admin portal](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) [Embed the Scalekit Admin Portal into your app via **iframe**. Node.js example for generating secure admin sessions](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) --- # DOCUMENT BOUNDARY --- # Developer resources > Get up and running with SDKs, APIs, and integration tools Coming soon --- # DOCUMENT BOUNDARY --- # Use Scalekit docs in your AI coding agent > Use Context7 to give your AI coding agent accurate, up-to-date Scalekit documentation so it can help you integrate faster and with fewer errors. AI coding agents like Claude Code and Cursor work from training data that can be months out of date. When you ask them to help integrate Scalekit, they may reference old APIs, deprecated patterns, or incorrect parameter names — leading to bugs that are hard to trace. [Context7](https://context7.com) provides two ways to access live, version-accurate documentation: * **CLI** — query docs directly from your terminal (recommended for most developers) * **MCP server** — integrates with AI agents for automatic doc injection Both methods pull the same up-to-date content. Choose CLI for direct control, or MCP server for seamless AI agent integration. Scalekit’s full developer documentation is indexed on Context7 at [context7.com/scalekit-inc/developer-docs](https://context7.com/scalekit-inc/developer-docs), covering hundreds of pages and thousands of code snippets across SSO, SCIM, MCP auth, agent auth, and connected accounts. ## Get accurate answers about Scalekit [Section titled “Get accurate answers about Scalekit”](#get-accurate-answers-about-scalekit) Context7 retrieves relevant documentation from the indexed Scalekit docs and delivers it to you or your agent. The AI then answers using accurate, current content rather than training data. Context7 provides three main capabilities: * `library` — resolve library IDs and discover docs * `docs` — fetch specific documentation sections * MCP server tools for AI agent integration 1. #### Set up Context7 [Section titled “Set up Context7”](#set-up-context7) Context7 can be set up via CLI or as an MCP server. Choose your method: * CLI Install the Context7 CLI to query docs directly from your terminal. **One-off installation via npx:** ```sh npx ctx7 --help ``` **Global installation:** ```sh npm install -g ctx7 ctx7 --version ``` Requires Node.js 18 or higher. The CLI provides three main capabilities: * **Fetch docs** — query specific documentation sections * **Manage skills** — generate AI agent skills for auto-invocation * **Configure MCP** — set up MCP server integration * MCP Server Context7 is configured as an MCP server in your coding agent. You can also add it directly from [context7.com](https://context7.com). Choose your tool: * Claude Code Run one of the following commands in your terminal: **Local (stdio):** ```sh claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp ``` **Remote (HTTP):** ```sh claude mcp add --scope user --transport http context7 https://mcp.context7.com/mcp ``` To verify the server was added: ```sh claude mcp list ``` * Cursor 1. Open **Settings > Cursor Settings > MCP** and click **Add New Global MCP Server**. Paste one of the following configs: **Remote server:** ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp" } } } ``` **Local server:** ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` 2. Restart Cursor. * Claude Desktop The easiest way is to install Context7 directly from the Claude Desktop interface: 1. Open Claude Desktop and go to **Customize > Connectors**. 2. Search for **Context7** and click **Install**. Alternatively, configure it manually via **Settings > Developer > Edit Config** and add to `claude_desktop_config.json`: ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` Restart Claude Desktop after saving. * Windsurf 1. Open **Settings > Developer > Edit Config** and open `windsurf_config.json`. 2. Add the following config and save: ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` 3. Restart Windsurf. * Claude Code Run one of the following commands in your terminal: **Local (stdio):** ```sh claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp ``` **Remote (HTTP):** ```sh claude mcp add --scope user --transport http context7 https://mcp.context7.com/mcp ``` To verify the server was added: ```sh claude mcp list ``` * Cursor 1. Open **Settings > Cursor Settings > MCP** and click **Add New Global MCP Server**. Paste one of the following configs: **Remote server:** ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp" } } } ``` **Local server:** ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` 2. Restart Cursor. * Claude Desktop The easiest way is to install Context7 directly from the Claude Desktop interface: 1. Open Claude Desktop and go to **Customize > Connectors**. 2. Search for **Context7** and click **Install**. Alternatively, configure it manually via **Settings > Developer > Edit Config** and add to `claude_desktop_config.json`: ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` Restart Claude Desktop after saving. * Windsurf 1. Open **Settings > Developer > Edit Config** and open `windsurf_config.json`. 2. Add the following config and save: ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` 3. Restart Windsurf. 2. #### Query Scalekit docs [Section titled “Query Scalekit docs”](#query-scalekit-docs) * Using CLI Querying Scalekit docs via CLI is a two-step process. **Step 1 — Resolve Scalekit library:** ```sh ctx7 library scalekit "How to set up SSO" ctx7 library scalekit "SCIM user provisioning" ctx7 library scalekit "MCP authentication setup" ``` Expected result for library selection: | Field | Description | | ----------------- | ----------------------------------- | | Library ID | `/scalekit-inc/developer-docs` | | Code Snippets | High (hundreds of indexed examples) | | Source Reputation | High | | Benchmark Score | Quality score from 0 to 100 | **Step 2 — Fetch Scalekit docs:** ```sh # SSO queries ctx7 docs /scalekit-inc/developer-docs "How to set up SSO with Scalekit" ctx7 docs /scalekit-inc/developer-docs "Configure SAML for enterprise SSO" # SCIM queries ctx7 docs /scalekit-inc/developer-docs "How to provision users with SCIM" ctx7 docs /scalekit-inc/developer-docs "Set up SCIM for Active Directory" # MCP auth queries ctx7 docs /scalekit-inc/developer-docs "Add MCP auth to my server" ctx7 docs /scalekit-inc/developer-docs "Configure agent authentication" # Connected accounts queries ctx7 docs /scalekit-inc/developer-docs "Configure connected accounts for GitHub OAuth" ctx7 docs /scalekit-inc/developer-docs "Set up Google OAuth integration" # JSON output for scripting ctx7 docs /scalekit-inc/developer-docs "SSO setup" --json # Pipe to other tools ctx7 docs /scalekit-inc/developer-docs "SCIM provisioning" | head -50 ``` * Using MCP Server Once Context7 is running, add **`use context7`** to any prompt where you want current Scalekit documentation injected automatically. **General Scalekit queries:** ```txt How do I set up SSO with Scalekit? use context7 ``` ```txt Show me how to provision users with SCIM using Scalekit. use context7 ``` **Target Scalekit docs directly** using the library path: ```txt use library /scalekit-inc/developer-docs for how to add MCP auth to my server ``` **Combine with version or feature specificity:** ```txt How do I configure connected accounts for GitHub OAuth with Scalekit? use context7 ``` 3. #### Auto-invoke Context7 (optional) [Section titled “Auto-invoke Context7 (optional)”](#auto-invoke-context7-optional) Configure your coding agent to always use Context7 for library and API questions — no need to add “use context7” manually each time. * CLI Use `ctx7 setup --cli` to configure Context7 for AI coding agents. This installs a `docs` skill that guides the agent to use `ctx7 library` and `ctx7 docs` commands for Scalekit documentation. **Setup commands:** ```sh # Interactive setup (prompts for agent) ctx7 setup --cli # Direct setup for specific agents ctx7 setup --cli --claude # Claude Code (~/.claude/skills) ctx7 setup --cli --cursor # Cursor (~/.cursor/skills) ctx7 setup --cli --universal # Universal (~/.config/agents/skills) # Project-specific setup (default is global) ctx7 setup --cli --project # Skip confirmation prompts ctx7 setup --cli --yes ``` **What gets installed — CLI + Skills mode:** | File | Purpose | | ---------------------- | --------------------------------------------------------------------- | | Agent skills directory | `docs` skill — guides the agent to use `ctx7 library` and `ctx7 docs` | When the `docs` skill is installed, your AI agent will automatically use `ctx7` commands to fetch accurate Scalekit documentation when asked about SSO, SCIM, MCP auth, or other Scalekit features. * MCP Server Configure your coding agent to always use Context7 for library and API questions — no need to add “use context7” manually each time. * Claude Code Add the following rule to your project’s `CLAUDE.md` file: ```md Always use Context7 MCP when I need library or API documentation, code generation, or setup and configuration steps. ``` This applies project-wide. For a global rule, add it to `~/.claude/CLAUDE.md`. * Cursor Open **Settings > Cursor Settings > Rules** and add: ```txt Always use Context7 MCP when I need library or API documentation, code generation, or setup and configuration steps. ``` * Claude Code Add the following rule to your project’s `CLAUDE.md` file: ```md Always use Context7 MCP when I need library or API documentation, code generation, or setup and configuration steps. ``` This applies project-wide. For a global rule, add it to `~/.claude/CLAUDE.md`. * Cursor Open **Settings > Cursor Settings > Rules** and add: ```txt Always use Context7 MCP when I need library or API documentation, code generation, or setup and configuration steps. ``` 4. #### Increase rate limits with an API key [Section titled “Increase rate limits with an API key”](#increase-rate-limits-with-an-api-key) The free tier of Context7 has rate limits. For heavier usage or team environments, get a free API key from [context7.com/dashboard](https://context7.com/dashboard) and add it to your configuration. * MCP Server * Claude Code **Local:** ```sh claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp --api-key YOUR_API_KEY ``` **Remote:** ```sh claude mcp add --scope user --header "CONTEXT7_API_KEY: YOUR_API_KEY" --transport http context7 https://mcp.context7.com/mcp ``` * Cursor **Remote server with API key:** ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp", "headers": { "CONTEXT7_API_KEY": "YOUR_API_KEY" } } } } ``` **Local server with API key:** ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp", "--api-key", "YOUR_API_KEY"] } } } ``` * Claude Desktop / Windsurf ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp", "--api-key", "YOUR_API_KEY"] } } } ``` * CLI **Local:** ```sh claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp --api-key YOUR_API_KEY ``` **Remote:** ```sh claude mcp add --scope user --header "CONTEXT7_API_KEY: YOUR_API_KEY" --transport http context7 https://mcp.context7.com/mcp ``` * Claude Code **Remote server with API key:** ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp", "headers": { "CONTEXT7_API_KEY": "YOUR_API_KEY" } } } } ``` **Local server with API key:** ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp", "--api-key", "YOUR_API_KEY"] } } } ``` * Cursor ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp", "--api-key", "YOUR_API_KEY"] } } } ``` * Claude Desktop / Windsurf Set an API key via environment variable for higher rate limits: ```sh # Set API key for current session export CONTEXT7_API_KEY=your_key # Add to ~/.bashrc or ~/.zshrc for permanent use echo 'export CONTEXT7_API_KEY=your_key' >> ~/.bashrc ``` API keys start with `ctx7sk`. If authentication fails with a 401 error, verify the key format matches your method (HTTP header for MCP, environment variable for CLI). --- # DOCUMENT BOUNDARY --- # Cursor Integration > Use Scalekit with Cursor via the local installer while the marketplace listing is under review Use Scalekit with Cursor by running the local installer, enabling the auth plugin you need, and then prompting Cursor to generate the implementation in your existing codebase. 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI detects Cursor and installs the authstack plugin directly. 2. ## Reload and select plugins Restart Cursor (or run **Developer: Reload Window**), then open **Settings > Cursor Settings > Plugins**. Enable the Scalekit plugins you need. The shipped skills are `integrate-agentkit`, `implement-saaskit`, `add-mcp-oauth`, `implement-sso`, and `implement-scim`. Done: the plugin list shows the skill you need. 3. ## Generate the implementation Open Cursor’s chat panel with **Cmd+L** (macOS) or **Ctrl+L** (Windows/Linux) and paste in an implementation prompt from the feature page (or describe what you need in natural language). The installed Scalekit plugins provide the agent with accurate patterns. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your application’s security requirements. 4. ## Verify the implementation After Cursor finishes generating code, confirm all authentication components are in place: * The Scalekit plugin appears in **Settings > Cursor Settings > Plugins** * Scalekit client initialized with your API credentials (set up a `.env` file with your Scalekit environment variables) * Authorization URL generation and callback handler * Session or token integration matching your application’s existing patterns --- # DOCUMENT BOUNDARY --- # Scalekit MCP Server > Learn how to use the Scalekit MCP Server to manage your users, organizations, and applications. Scalekit Model Context Protocol (MCP) server provides comprehensive tools for managing environments, organizations, users, connections, and workspace operations. Built for developers who want to connect their AI tools to Scalekit context and capabilities based on simple natural language queries. This MCP server enables AI assistants to interact with Scalekit’s identity and access management platform through a standardized set of tools. It provides secure, OAuth-protected access to manage environments, organizations, users, authentication connections, and more. * Environment management and configuration * Organization and user management * Workspace member administration * OIDC connection setup and management * MCP server registration and configuration * Role and scope management * Admin portal link generation ## Configuration [Section titled “Configuration”](#configuration) Connect the Scalekit MCP server to your AI coding tool. Find your tool below and follow the steps — your client will prompt you to sign in via OAuth on first use. ### Claude Code [Section titled “Claude Code”](#claude-code) Run this command in your terminal: ```bash 1 claude mcp add --transport http scalekit https://mcp.scalekit.com/ ``` ### Claude Desktop [Section titled “Claude Desktop”](#claude-desktop) 1. Open Claude Desktop 2. Go to **Settings → Connectors** 3. Click **Add custom connector** 4. Enter `Scalekit` as the name and `https://mcp.scalekit.com` as the URL 5. Click **Connect** to authenticate ### VS Code [Section titled “VS Code”](#vs-code) Edit `.vscode/mcp.json` in your project (requires VS Code 1.101 or later): ```json 1 { 2 "servers": { 3 "scalekit": { 4 "type": "http", 5 "url": "https://mcp.scalekit.com/" 6 } 7 } 8 } ``` ### Cursor [Section titled “Cursor”](#cursor) Edit `~/.cursor/mcp.json`, or open **Cursor Settings → MCP → Add New Global MCP Server** and paste the config: ```json 1 { 2 "mcpServers": { 3 "scalekit": { 4 "url": "https://mcp.scalekit.com/" 5 } 6 } 7 } ``` ### Windsurf [Section titled “Windsurf”](#windsurf) Edit `~/.codeium/windsurf/mcp_config.json`: ```json 1 { 2 "mcpServers": { 3 "scalekit": { 4 "serverUrl": "https://mcp.scalekit.com/" 5 } 6 } 7 } ``` ### Gemini CLI [Section titled “Gemini CLI”](#gemini-cli) Edit `~/.gemini/settings.json`: ```json 1 { 2 "mcpServers": { 3 "scalekit": { 4 "httpUrl": "https://mcp.scalekit.com/" 5 } 6 } 7 } ``` ### Codex [Section titled “Codex”](#codex) Run this command in your terminal: ```bash 1 codex mcp add scalekit --url https://mcp.scalekit.com/ ``` ### OpenCode [Section titled “OpenCode”](#opencode) Edit `opencode.json` in your project root: ```json 1 { 2 "mcp": { 3 "scalekit": { 4 "type": "remote", 5 "url": "https://mcp.scalekit.com/", 6 "enabled": true 7 } 8 } 9 } ``` ### Roo Code [Section titled “Roo Code”](#roo-code) Add to your MCP configuration: ```json 1 { 2 "mcpServers": { 3 "scalekit": { 4 "type": "streamable-http", 5 "url": "https://mcp.scalekit.com/" 6 } 7 } 8 } ``` ### Zed [Section titled “Zed”](#zed) Add to your Zed `settings.json`: ```json 1 { 2 "context_servers": { 3 "scalekit": { 4 "url": "https://mcp.scalekit.com/" 5 } 6 } 7 } ``` ### Kiro [Section titled “Kiro”](#kiro) Edit `~/.kiro/settings/mcp.json`: ```json 1 { 2 "mcpServers": { 3 "scalekit": { 4 "url": "https://mcp.scalekit.com/" 5 } 6 } 7 } ``` ### Warp [Section titled “Warp”](#warp) Go to **Settings → MCP Servers → Add MCP Server** and enter `https://mcp.scalekit.com/`, or add to your Warp MCP config: ```json 1 { 2 "scalekit": { 3 "serverUrl": "https://mcp.scalekit.com/" 4 } 5 } ``` ### v0 by Vercel [Section titled “v0 by Vercel”](#v0-by-vercel) Go to **Prompt Tools → Add MCP** and enter `https://mcp.scalekit.com/`. ## GitHub [Section titled “GitHub”](#github) The source code for the Scalekit MCP server is available on [GitHub](https://github.com/scalekit-inc/mcp), including a full list of available tools and their descriptions. * Open an issue if you find a bug or have a question. * Submit a PR or open an issue to suggest new tools. --- # DOCUMENT BOUNDARY --- # OpenAPI Specifications > Access Scalekit OpenAPI specifications for API documentation and client generation ### [OpenAPI Spec](https://github.com/scalekit-inc/developer-docs/blob/main/public/api/scalekit.scalar.yaml) [YAMLv3.1.1](https://github.com/scalekit-inc/developer-docs/blob/main/public/api/scalekit.scalar.yaml) [Download the OpenAPI specification](https://github.com/scalekit-inc/developer-docs/blob/main/public/api/scalekit.scalar.yaml) ### [OpenAPI Spec](https://github.com/scalekit-inc/developer-docs/blob/main/public/api/scalekit.scalar.json) [JSONv3.1.1](https://github.com/scalekit-inc/developer-docs/blob/main/public/api/scalekit.scalar.json) [Download the OpenAPI specification](https://github.com/scalekit-inc/developer-docs/blob/main/public/api/scalekit.scalar.json) --- # DOCUMENT BOUNDARY --- # Build with AI > Use AI coding agents to implement Scalekit authentication in minutes Use the Scalekit CLI to install the authstack plugin for your coding agents. One command detects your tools and sets everything up. * Recommended Terminal ```bash npx @scalekit-inc/cli setup ``` * Global install (for repeated use) Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for Claude Code, Cursor, GitHub Copilot, and Codex. Then load a shipped skill: `integrate-agentkit`, `implement-saaskit`, `add-mcp-oauth`, `implement-sso`, or `implement-scim`. Done: the command exits 0 and the skill you need is available. ### [Full Stack Auth](/dev-kit/build-with-ai/full-stack-auth/) ### [AgentKit](/cookbooks/set-up-agentkit-with-your-coding-agent/) ### [MCP Auth](/dev-kit/build-with-ai/mcp-auth/) ### [Modular SSO](/dev-kit/build-with-ai/sso/) ### [Modular SCIM](/dev-kit/build-with-ai/scim/) ## Documentation for AI agents [Section titled “Documentation for AI agents”](#documentation-for-ai-agents) Load these files to give your agent full context about Scalekit APIs and integration patterns: | File | Contents | When to use | | ---------------------------------------------------------- | ---------------------------------------------------- | --------------------------------- | | [`/llms.txt`](/llms.txt) | Structured index with routing hints per product area | Most queries — smaller context | | [`/llms-full.txt`](/llms-full.txt) | Complete documentation for all pages | When exhaustive context is needed | | [`sitemap-0.xml`](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of all documentation pages | Crawling or indexing all pages | --- # DOCUMENT BOUNDARY --- # Coding agents: Add full-stack auth to your app > Let your coding agents guide you into implementing Scalekit full-stack authentication in minutes Install the authstack plugin, then tell your coding agent to add SaaSKit auth to your app. * Claude Code 1. ## Install the authstack plugin Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Select Claude Code when prompted. The CLI installs the authstack plugin for you. Then ask the agent to run the shipped skill `implement-saaskit`. Done: the command exits 0 and `implement-saaskit` is available. 2. ## Generate authentication implementation Copy the following prompt into your coding agent: Authentication implementation prompt ```md Add SaaSKit auth to my app. I need login, sessions, and logout. ``` Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After the coding agent completes, verify that all authentication components are properly configured: Check generated files: * Scalekit client initialization with environment credentials (you may need to set up a `.env` file with your Scalekit API credentials) * Login route that redirects to Scalekit’s authorization endpoint * OAuth callback route that exchanges the code for tokens * Secure session storage with proper cookie attributes * Logout endpoint that clears the session The login flow should redirect users to Scalekit’s authorization page, where they authenticate. Your application should then exchange the returned authorization code for tokens, store the session, and redirect the user to the protected area of your app. * Codex 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Choose Codex when prompted. The CLI installs the authstack plugin. Then load the shipped skill `implement-saaskit`. Done: the command exits 0 and `implement-saaskit` is available. 2. ## Enable the SaaSKit plugin Restart Codex and enable the authstack plugin in the Plugin Directory. 3. ## Generate the authentication implementation Copy the following prompt into Codex: Authentication implementation prompt ```md Add SaaSKit auth to my app. I need login, sessions, and logout. ``` Codex loads the SaaSKit plugin from the authstack plugin, analyzes your existing application structure, generates Scalekit client initialization with environment credentials, creates the login redirect handler, implements the OAuth callback to exchange the authorization code for tokens, and adds secure session storage with a logout endpoint. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 4. ## Verify the implementation After Codex completes, verify that all authentication components are properly configured: Check generated files: * Scalekit client initialization with environment credentials. You may need to set up a `.env` file with your Scalekit API credentials. * Login route that redirects to Scalekit’s authorization endpoint * OAuth callback route that exchanges the code for tokens * Secure session storage with proper cookie attributes * Logout endpoint that clears session state The login flow should redirect users to Scalekit’s authorization page, where they authenticate. Your application should then exchange the returned authorization code for tokens, store the session, and redirect the user to the protected area of your app. When you connect, users authenticate through the OAuth 2.0 flow you configured. Verify that protected routes require a valid session and that the logout endpoint properly clears session state. * GitHub Copilot CLI 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for GitHub Copilot. Then ask the agent to run the shipped skill `implement-saaskit`. Done: the command exits 0 and `implement-saaskit` is available. 2. ## Generate authentication implementation Copy the following command into your terminal: Terminal ```bash copilot "Add SaaSKit auth to my app. I need login, sessions, and logout." ``` GitHub Copilot uses the SaaSKit plugin to analyze your existing application structure, generate Scalekit client initialization code, create the login redirect handler, implement the OAuth callback for token exchange, add secure session storage, and provide a logout endpoint. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After GitHub Copilot completes, verify that all authentication components are properly configured: Check generated files: * Scalekit client initialization with environment credentials (you may need to set up a `.env` file with your Scalekit API credentials) * Login route that redirects to Scalekit’s authorization endpoint * OAuth callback route that exchanges the code for tokens * Secure session storage with proper cookie attributes * Logout endpoint that clears the session The login flow should redirect users to Scalekit’s authorization page, where they authenticate. Your application should then exchange the returned authorization code for tokens, store the session, and redirect the user to the protected area of your app. When you connect, users authenticate through the OAuth 2.0 flow you configured. Verify that protected routes require a valid session and that the logout endpoint properly clears session state. * Cursor 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI detects Cursor and installs the authstack plugin directly. 2. ## Reload and select plugins Restart Cursor (or run **Developer: Reload Window**), then open **Settings > Cursor Settings > Plugins**. Enable the Scalekit plugins you need. The shipped skills are `integrate-agentkit`, `implement-saaskit`, `add-mcp-oauth`, `implement-sso`, and `implement-scim`. Done: the plugin list shows the skill you need. 3. ## Generate the implementation Open Cursor’s chat panel with **Cmd+L** (macOS) or **Ctrl+L** (Windows/Linux) and paste in an implementation prompt from the feature page (or describe what you need in natural language). The installed Scalekit plugins provide the agent with accurate patterns. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your application’s security requirements. 4. ## Verify the implementation After Cursor finishes generating code, confirm all authentication components are in place: * The Scalekit plugin appears in **Settings > Cursor Settings > Plugins** * Scalekit client initialized with your API credentials (set up a `.env` file with your Scalekit environment variables) * Authorization URL generation and callback handler * Session or token integration matching your application’s existing patterns * 40+ agents The authstack plugin works with 40+ AI agents. Skills are installed via the Scalekit CLI or the Vercel Skills CLI. The easiest way for most developers is: Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Then choose the “Other agents” / skills option when prompted. You can also install the skills directly: 1. ## Install interactively Run the command with no flags to be guided through the available skills: Terminal ```bash npx skills add scalekit-inc/authstack ``` 2. ## Browse and install a specific skill Install the skill for your auth type (for example, MCP OAuth): Terminal ```bash # List all available skills npx skills add scalekit-inc/authstack --list # Install a specific skill npx skills add scalekit-inc/authstack --skill add-mcp-oauth ``` 3. ## Invoke the skill Varies by agent Each coding agent has its own behavior for invoking skills. In OpenCode, skills are invoked **automatically by the agent based on natural language** — no slash commands required. The agent has a list of available skills and their `description` fields in context. It reads your intent, matches it against those descriptions, and autonomously calls the skill tool to load the relevant `SKILL.md`. A clear, specific `description` in skill frontmatter is what the agent uses to decide which skill to invoke. **Flow in practice:** * You write a natural language message to the agent * The agent checks its context — it already sees `` with names and descriptions * If your request matches a skill’s purpose, the agent calls `skill("")` internally * The full `SKILL.md` content loads into context and the agent follows those instructions If your agent does not automatically pick up skills, you can run a command to load a skill and manually select Scalekit’s skills to load into context. Refer to your favorite coding agent’s documentation for how to invoke skills once they are installed. 4. ## Install all skills globally To add all Scalekit authentication skills to your agents: Terminal ```bash npx skills add scalekit-inc/authstack --all --global ``` This installs all AgentKit and SaaSKit skills. --- # DOCUMENT BOUNDARY --- # MCP quickstart with AI coding agents > Use AI coding agents to add OAuth 2.1 authentication to your MCP servers in minutes Use AI coding agents like Claude Code, GitHub Copilot CLI, Cursor, and OpenCode to add Scalekit’s OAuth 2.1 authentication to your MCP servers. Configure the agents to analyze your codebase, apply consistent authentication patterns, and generate production-ready code that integrates OAuth 2.1 end-to-end. This reduces implementation time from hours to minutes and follows security best practices. **Prerequisites** * A [Scalekit account](https://app.scalekit.com) with MCP server management access * Basic familiarity with OAuth 2.1 and MCP server architecture * Terminal access for installing coding agent tools - Claude Code 1. ## Install the authstack plugin Not yet on Claude Code? Follow the [official quickstart guide](https://code.claude.com/docs/en/quickstart) to install it. Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for you. Then ask the agent to run the shipped skill `add-mcp-oauth`. Done: the command exits 0 and `add-mcp-oauth` is available. 2. ## Generate authentication implementation Use a structured prompt to direct the coding agent. A well-formed prompt ensures the agent generates complete, production-ready authentication code that includes all required security components. Copy the following prompt into your coding agent: Authentication implementation prompt ```md Add OAuth 2.1 authentication to my MCP server using Scalekit. Initialize ScalekitClient with environment credentials, implement /.well-known/ metadata endpoint for discovery, and add authentication middleware that validates JWT bearer tokens on all MCP requests. Code only. ``` When you submit this prompt, Claude Code loads the MCP authentication skill from the marketplace -> analyzes your existing MCP server structure -> generates authentication middleware with token validation -> creates the OAuth discovery endpoint -> configures environment variable handling. ![Claude Code activating MCP authentication skill](/.netlify/images?url=_astro%2Fskill-activation.CGYr0u-q.png\&w=1121\&h=858\&dpl=6aaa70ad2ea7b40008ad2afd) Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify and test the implementation After the coding agent completes, verify that all authentication components are properly configured: Check generated files: * Authentication middleware with JWT validation * Environment variable configuration (`.env.example`) * OAuth discovery endpoint (`/.well-known/oauth-authorization-server`) * Error handling for invalid or expired tokens **Test the authentication flow:** * Claude Code Claude REPL ```md Now that your MCP server has authentication integrated, let's verify it's working correctly by testing the flow step by step. First, start your MCP server using npm start (Node.js) or python server.py (Python) and confirm it's running without errors. Next, test the OAuth discovery endpoint by running curl http://localhost:3000/.well-known/oauth-authorization-server to verify your server exposes the correct authorization configuration. Then, verify authentication is enforced by calling curl http://localhost:3000/mcp without credentials—this should return a 401 Unauthorized response, confirming protected endpoints are secured. Finally, test with a valid token by running curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp (replace YOUR_TOKEN with an actual access token from your auth provider) to confirm authenticated requests succeed and return the expected response—if all these steps work as described, your authentication implementation is functioning correctly. ``` * Node.js Terminal ```bash 1 # Start your MCP server 2 npm start 3 4 # Test discovery endpoint 5 curl http://localhost:3000/.well-known/oauth-authorization-server 6 7 # Test protected endpoint (should return 401) 8 curl http://localhost:3000/mcp 9 10 # Test with valid token 11 curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp ``` * Python Terminal ```bash 1 # Start your MCP server 2 python server.py 3 4 # Test discovery endpoint 5 curl http://localhost:3000/.well-known/oauth-authorization-server 6 7 # Test protected endpoint (should return 401) 8 curl http://localhost:3000/mcp 9 10 # Test with valid token 11 curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp ``` The discovery endpoint should return OAuth configuration metadata. Protected endpoints should reject requests without valid tokens and accept requests with properly scoped access tokens. - Codex Claude REPL ```md Now that your MCP server has authentication integrated, let's verify it's working correctly by testing the flow step by step. First, start your MCP server using npm start (Node.js) or python server.py (Python) and confirm it's running without errors. Next, test the OAuth discovery endpoint by running curl http://localhost:3000/.well-known/oauth-authorization-server to verify your server exposes the correct authorization configuration. Then, verify authentication is enforced by calling curl http://localhost:3000/mcp without credentials—this should return a 401 Unauthorized response, confirming protected endpoints are secured. Finally, test with a valid token by running curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp (replace YOUR_TOKEN with an actual access token from your auth provider) to confirm authenticated requests succeed and return the expected response—if all these steps work as described, your authentication implementation is functioning correctly. ``` - GitHub Copilot CLI Terminal ```bash 1 # Start your MCP server 2 npm start 3 4 # Test discovery endpoint 5 curl http://localhost:3000/.well-known/oauth-authorization-server 6 7 # Test protected endpoint (should return 401) 8 curl http://localhost:3000/mcp 9 10 # Test with valid token 11 curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp ``` - Cursor Terminal ```bash 1 # Start your MCP server 2 python server.py 3 4 # Test discovery endpoint 5 curl http://localhost:3000/.well-known/oauth-authorization-server 6 7 # Test protected endpoint (should return 401) 8 curl http://localhost:3000/mcp 9 10 # Test with valid token 11 curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp ``` - 40+ agents 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Choose Codex when prompted. The CLI installs the authstack plugin. Done: the command exits 0. 2. ## Enable the MCP OAuth skill Restart Codex, then open the Plugin Directory and enable the authstack plugin. Load the shipped skill `add-mcp-oauth`. That skill includes the workflows, framework-specific guidance, and references Codex uses to generate OAuth 2.1 protection for remote MCP servers. Done: `add-mcp-oauth` is available to Codex. 3. ## Generate the authentication implementation Use a structured prompt to direct Codex. A well-formed prompt helps Codex generate complete, production-ready authentication code that includes all required security components. Copy the following prompt into Codex: Authentication implementation prompt ```md Add OAuth 2.1 authentication to my MCP server using Scalekit. Initialize ScalekitClient with environment credentials, implement /.well-known/ metadata endpoint for discovery, and add authentication middleware that validates JWT bearer tokens on all MCP requests. Code only. ``` When you submit this prompt, Codex loads the MCP Auth plugin from the authstack plugin, analyzes your existing MCP server structure, generates authentication middleware with token validation, creates the OAuth discovery endpoint, and configures environment variable handling. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 4. ## Verify and test the implementation After Codex completes, verify that all authentication components are properly configured: Check generated files: * Authentication middleware with JWT validation * Environment variable configuration (`.env.example`) * OAuth discovery endpoint (`/.well-known/oauth-authorization-server`) * Error handling for invalid or expired tokens Test the authentication flow: Terminal ```bash 1 # Start your MCP server 2 npm start 3 4 # Test discovery endpoint 5 curl http://localhost:3000/.well-known/oauth-authorization-server 6 7 # Test protected endpoint (should return 401) 8 curl http://localhost:3000/mcp 9 10 # Test with valid token 11 curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp ``` The discovery endpoint should return OAuth configuration metadata. Protected endpoints should reject requests without valid tokens and accept requests with properly scoped access tokens. - Claude Code 1. ## Install the authstack plugin (recommended) Need to install GitHub Copilot CLI? See the [getting started guide](https://docs.github.com/en/copilot/how-tos/copilot-cli/cli-getting-started) — an active GitHub Copilot subscription is required. Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for GitHub Copilot. Then ask the agent to run the shipped skill `add-mcp-oauth`. Done: the command exits 0 and `add-mcp-oauth` is available. 2. ## Generate authentication implementation Use a structured prompt to direct GitHub Copilot. A well-formed prompt ensures the agent generates complete, production-ready authentication code that includes all required security components. Copy the following command into your terminal: Terminal ```bash copilot "Add OAuth 2.1 authentication to my MCP server using Scalekit. Initialize ScalekitClient with environment credentials, implement /.well-known/ metadata endpoint for discovery, and add authentication middleware that validates JWT bearer tokens on all MCP requests. Code only." ``` GitHub Copilot uses the MCP Auth plugin to analyze your existing MCP server structure, generate authentication middleware with token validation, create the OAuth discovery endpoint, and configure environment variable handling. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After GitHub Copilot completes, verify that all authentication components are properly configured: Check generated files: * Authentication middleware with JWT validation * Environment variable configuration (`.env.example`) * OAuth discovery endpoint (`/.well-known/oauth-authorization-server`) * Error handling for invalid or expired tokens Test the authentication flow: Terminal ```bash 1 # Start your MCP server 2 npm start 3 4 # Test discovery endpoint 5 curl http://localhost:3000/.well-known/oauth-authorization-server 6 7 # Test protected endpoint (should return 401) 8 curl http://localhost:3000/mcp 9 10 # Test with valid token 11 curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/mcp ``` The discovery endpoint should return OAuth configuration metadata. Protected endpoints should reject requests without valid tokens and accept requests with properly scoped access tokens. - Node.js 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI detects Cursor and installs the authstack plugin directly. 2. ## Reload and select plugins Restart Cursor (or run **Developer: Reload Window**), then open **Settings > Cursor Settings > Plugins**. Enable the Scalekit plugins you need. The shipped skills are `integrate-agentkit`, `implement-saaskit`, `add-mcp-oauth`, `implement-sso`, and `implement-scim`. Done: the plugin list shows the skill you need. 3. ## Generate the implementation Open Cursor’s chat panel with **Cmd+L** (macOS) or **Ctrl+L** (Windows/Linux) and paste in an implementation prompt from the feature page (or describe what you need in natural language). The installed Scalekit plugins provide the agent with accurate patterns. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your application’s security requirements. 4. ## Verify the implementation After Cursor finishes generating code, confirm all authentication components are in place: * The Scalekit plugin appears in **Settings > Cursor Settings > Plugins** * Scalekit client initialized with your API credentials (set up a `.env` file with your Scalekit environment variables) * Authorization URL generation and callback handler * Session or token integration matching your application’s existing patterns - Python The authstack plugin works with 40+ AI agents. Skills are installed via the Scalekit CLI or the Vercel Skills CLI. The easiest way for most developers is: Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Then choose the “Other agents” / skills option when prompted. You can also install the skills directly: 1. ## Install interactively Run the command with no flags to be guided through the available skills: Terminal ```bash npx skills add scalekit-inc/authstack ``` 2. ## Browse and install a specific skill Install the skill for your auth type (for example, MCP OAuth): Terminal ```bash # List all available skills npx skills add scalekit-inc/authstack --list # Install a specific skill npx skills add scalekit-inc/authstack --skill add-mcp-oauth ``` 3. ## Invoke the skill Varies by agent Each coding agent has its own behavior for invoking skills. In OpenCode, skills are invoked **automatically by the agent based on natural language** — no slash commands required. The agent has a list of available skills and their `description` fields in context. It reads your intent, matches it against those descriptions, and autonomously calls the skill tool to load the relevant `SKILL.md`. A clear, specific `description` in skill frontmatter is what the agent uses to decide which skill to invoke. **Flow in practice:** * You write a natural language message to the agent * The agent checks its context — it already sees `` with names and descriptions * If your request matches a skill’s purpose, the agent calls `skill("")` internally * The full `SKILL.md` content loads into context and the agent follows those instructions If your agent does not automatically pick up skills, you can run a command to load a skill and manually select Scalekit’s skills to load into context. Refer to your favorite coding agent’s documentation for how to invoke skills once they are installed. 4. ## Install all skills globally To add all Scalekit authentication skills to your agents: Terminal ```bash npx skills add scalekit-inc/authstack --all --global ``` This installs all AgentKit and SaaSKit skills. ## Next steps [Section titled “Next steps”](#next-steps) Your MCP server now has OAuth 2.1 authentication integrated. Test the implementation with your MCP host to verify the authentication flow works correctly. ### Test with MCP hosts [Section titled “Test with MCP hosts”](#test-with-mcp-hosts) Connect your authenticated MCP server to any MCP-compatible host: * **Claude Desktop or Claude Code**: Configure the MCP server connection in settings * **Cursor**: Add the MCP server to your workspace configuration * **Windsurf**: Register the server in your MCP settings * **Other MCP hosts**: Follow your host’s documentation for connecting authenticated MCP servers When you connect, the host authenticates using the OAuth 2.1 flow you configured. Verify that protected MCP resources require valid access tokens and that the discovery endpoint provides correct OAuth metadata. --- # DOCUMENT BOUNDARY --- # Coding agents: Add SCIM directory sync to your app > Let your coding agents guide you into adding Scalekit SCIM provisioning to your application in minutes Use AI coding agents like Claude Code, GitHub Copilot CLI, Cursor, and OpenCode to add Scalekit’s Modular SCIM directory sync to your applications. Configure the agents to analyze your codebase, apply SCIM patterns, and generate production-ready code for user provisioning, deprovisioning, and lifecycle management. This follows security best practices and reduces implementation time from hours to minutes. * Claude Code 1. ## Install the authstack plugin Not yet on Claude Code? Follow the [official quickstart guide](https://code.claude.com/docs/en/quickstart) to install it. Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for you. Then ask the agent to run the shipped skill `implement-scim`. Done: the command exits 0 and `implement-scim` is available. 2. ## Generate SCIM implementation Use a structured prompt to direct the coding agent. A well-formed prompt ensures the agent generates complete, production-ready SCIM code that includes all required security components. Copy the following prompt into your coding agent: SCIM implementation prompt ```md Guide the coding agent to add Scalekit SCIM directory sync to my app — set up the webhook endpoint to receive SCIM events, validate the webhook signature, and handle user provisioning and deprovisioning events to create, update, and delete users in my database. Code only. ``` When you submit this prompt, Claude Code loads the Modular SCIM skill from the marketplace -> analyzes your existing application structure -> generates a webhook endpoint to receive SCIM events from Scalekit -> implements webhook signature validation to prevent unauthorized requests -> creates handlers for user provisioning events (create and update) -> adds deprovisioning logic to delete or deactivate users in your database. Review generated code Always review AI-generated SCIM code before deployment. Verify that webhook signature validation, event handling logic, and database operations match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After the coding agent completes, verify that all SCIM components are properly configured: Check generated files: * Webhook endpoint that receives SCIM events from Scalekit (you may need to set up a `.env` file with your Scalekit webhook secret) * Webhook signature validation to authenticate incoming requests * User provisioning handler that creates or updates users in your database * Deprovisioning handler that deletes or deactivates users when they are removed from the identity provider The SCIM flow should receive webhook events from Scalekit when users are added, updated, or removed in the connected identity provider. Your application should validate each event’s signature, then apply the corresponding change to your user database. When directory sync is active, user lifecycle changes in the identity provider propagate automatically to your application. Verify that provisioning events correctly create or update users, and that deprovisioning events properly remove or deactivate accounts. * Codex 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Choose Codex when prompted. The CLI installs the authstack plugin. Done: the command exits 0. 2. ## Enable the SCIM skill Restart Codex, then open the Plugin Directory and enable the authstack plugin. Load the shipped skill `implement-scim`. That skill includes the workflows, references, and prompts Codex uses to generate SCIM provisioning and deprovisioning code for your application. Done: `implement-scim` is available to Codex. 3. ## Generate the SCIM implementation Use a structured prompt to direct Codex. A well-formed prompt helps Codex generate complete, production-ready SCIM code that includes all required security components. Copy the following prompt into Codex: SCIM implementation prompt ```md Guide the coding agent to add Scalekit SCIM directory sync to my app — set up the webhook endpoint to receive SCIM events, validate the webhook signature, and handle user provisioning and deprovisioning events to create, update, and delete users in my database. Code only. ``` When you submit this prompt, Codex loads the Modular SCIM plugin from the authstack plugin, analyzes your existing application structure, generates a webhook endpoint to receive SCIM events from Scalekit, implements webhook signature validation to prevent unauthorized requests, creates handlers for user provisioning events, and adds deprovisioning logic to delete or deactivate users in your database. Review generated code Always review AI-generated SCIM code before deployment. Verify that webhook signature validation, event handling logic, and database operations match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 4. ## Verify the implementation After Codex completes, verify that all SCIM components are properly configured: Check generated files: * Webhook endpoint that receives SCIM events from Scalekit. You may need to set up a `.env` file with your Scalekit webhook secret. * Webhook signature validation to authenticate incoming requests * User provisioning handler that creates or updates users in your database * Deprovisioning handler that deletes or deactivates users when they are removed from the identity provider The SCIM flow should receive webhook events from Scalekit when users are added, updated, or removed in the connected identity provider. Your application should validate each event’s signature, then apply the corresponding change to your user database. When directory sync is active, user lifecycle changes in the identity provider propagate automatically to your application. Verify that provisioning events correctly create or update users, and that deprovisioning events properly remove or deactivate accounts. * GitHub Copilot CLI 1. ## Install the authstack plugin (recommended) Need to install GitHub Copilot CLI? See the [getting started guide](https://docs.github.com/en/copilot/how-tos/copilot-cli/cli-getting-started) — an active GitHub Copilot subscription is required. Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for GitHub Copilot. Then ask the agent to run the shipped skill `implement-scim`. Done: the command exits 0 and `implement-scim` is available. 2. ## Generate SCIM implementation Use a structured prompt to direct GitHub Copilot. A well-formed prompt ensures the agent generates complete, production-ready SCIM code that includes all required security components. Copy the following command into your terminal: Terminal ```bash copilot "Add Scalekit SCIM directory sync to my app — set up the webhook endpoint to receive SCIM events, validate the webhook signature, and handle user provisioning and deprovisioning events to create, update, and delete users in my database. Code only." ``` GitHub Copilot uses the Modular SCIM plugin to analyze your existing application structure, generate a webhook endpoint to receive SCIM events from Scalekit, implement webhook signature validation to prevent unauthorized requests, create handlers for user provisioning events (create and update), and add deprovisioning logic to delete or deactivate users in your database. Review generated code Always review AI-generated SCIM code before deployment. Verify that webhook signature validation, event handling logic, and database operations match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After GitHub Copilot completes, verify that all SCIM components are properly configured: Check generated files: * Webhook endpoint that receives SCIM events from Scalekit (you may need to set up a `.env` file with your Scalekit webhook secret) * Webhook signature validation to authenticate incoming requests * User provisioning handler that creates or updates users in your database * Deprovisioning handler that deletes or deactivates users when they are removed from the identity provider The SCIM flow should receive webhook events from Scalekit when users are added, updated, or removed in the connected identity provider. Your application should validate each event’s signature, then apply the corresponding change to your user database. When directory sync is active, user lifecycle changes in the identity provider propagate automatically to your application. Verify that provisioning events correctly create or update users, and that deprovisioning events properly remove or deactivate accounts. * Cursor 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI detects Cursor and installs the authstack plugin directly. 2. ## Reload and select plugins Restart Cursor (or run **Developer: Reload Window**), then open **Settings > Cursor Settings > Plugins**. Enable the Scalekit plugins you need. The shipped skills are `integrate-agentkit`, `implement-saaskit`, `add-mcp-oauth`, `implement-sso`, and `implement-scim`. Done: the plugin list shows the skill you need. 3. ## Generate the implementation Open Cursor’s chat panel with **Cmd+L** (macOS) or **Ctrl+L** (Windows/Linux) and paste in an implementation prompt from the feature page (or describe what you need in natural language). The installed Scalekit plugins provide the agent with accurate patterns. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your application’s security requirements. 4. ## Verify the implementation After Cursor finishes generating code, confirm all authentication components are in place: * The Scalekit plugin appears in **Settings > Cursor Settings > Plugins** * Scalekit client initialized with your API credentials (set up a `.env` file with your Scalekit environment variables) * Authorization URL generation and callback handler * Session or token integration matching your application’s existing patterns * 40+ agents The authstack plugin works with 40+ AI agents. Skills are installed via the Scalekit CLI or the Vercel Skills CLI. The easiest way for most developers is: Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Then choose the “Other agents” / skills option when prompted. You can also install the skills directly: 1. ## Install interactively Run the command with no flags to be guided through the available skills: Terminal ```bash npx skills add scalekit-inc/authstack ``` 2. ## Browse and install a specific skill Install the skill for your auth type (for example, MCP OAuth): Terminal ```bash # List all available skills npx skills add scalekit-inc/authstack --list # Install a specific skill npx skills add scalekit-inc/authstack --skill add-mcp-oauth ``` 3. ## Invoke the skill Varies by agent Each coding agent has its own behavior for invoking skills. In OpenCode, skills are invoked **automatically by the agent based on natural language** — no slash commands required. The agent has a list of available skills and their `description` fields in context. It reads your intent, matches it against those descriptions, and autonomously calls the skill tool to load the relevant `SKILL.md`. A clear, specific `description` in skill frontmatter is what the agent uses to decide which skill to invoke. **Flow in practice:** * You write a natural language message to the agent * The agent checks its context — it already sees `` with names and descriptions * If your request matches a skill’s purpose, the agent calls `skill("")` internally * The full `SKILL.md` content loads into context and the agent follows those instructions If your agent does not automatically pick up skills, you can run a command to load a skill and manually select Scalekit’s skills to load into context. Refer to your favorite coding agent’s documentation for how to invoke skills once they are installed. 4. ## Install all skills globally To add all Scalekit authentication skills to your agents: Terminal ```bash npx skills add scalekit-inc/authstack --all --global ``` This installs all AgentKit and SaaSKit skills. --- # DOCUMENT BOUNDARY --- # Coding agents: Add SSO to your app > Let your coding agents guide you into adding Scalekit SSO to your existing application in minutes Use AI coding agents like Claude Code, GitHub Copilot CLI, Cursor, and OpenCode to add Scalekit’s Modular SSO to your existing applications. Configure the agents to analyze your codebase, apply SSO patterns, and generate production-ready code that integrates enterprise identity providers. This follows security best practices while reducing implementation time from hours to minutes. * Claude Code 1. ## Install the authstack plugin Not yet on Claude Code? Follow the [official quickstart guide](https://code.claude.com/docs/en/quickstart) to install it. Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for you. Then ask the agent to run the shipped skill `implement-sso`. Done: the command exits 0 and `implement-sso` is available. 2. ## Generate SSO implementation Use a structured prompt to direct the coding agent. A well-formed prompt ensures the agent generates complete, production-ready SSO code that includes all required security components. Copy the following prompt into your coding agent: SSO implementation prompt ```md Guide the coding agent to add Scalekit SSO to my existing app — initialize ScalekitClient, generate an SSO authorization URL for a given organization, handle the SSO callback to validate and exchange the code for user identity, and integrate the SSO user into my existing session system. Code only. ``` When you submit this prompt, Claude Code loads the Modular SSO skill from the marketplace -> analyzes your existing application structure -> generates Scalekit client initialization with environment credentials -> creates an SSO authorization URL generator for organization-based routing -> implements the SSO callback handler to validate and exchange the code for user identity -> integrates SSO user data into your existing session system. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After the coding agent completes, verify that all SSO components are properly configured: Check generated files: * Scalekit client initialization with environment credentials (you may need to set up a `.env` file with your Scalekit API credentials) * SSO authorization URL generation for organization-based routing * SSO callback handler that validates the authorization code and retrieves user identity * Integration logic that maps SSO user identity into your existing session system The SSO flow should redirect users to their organization’s identity provider, where they authenticate. Your application should then receive the callback, validate the code, extract the user’s identity, and create or update the user session accordingly. When users authenticate through SSO, your application receives verified identity claims from the identity provider. Verify that the SSO callback correctly maps user identity to your application’s user model and that the session is created with the appropriate access level. * Codex 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Choose Codex when prompted. The CLI installs the authstack plugin. Done: the command exits 0. 2. ## Enable the SSO skill Restart Codex, then open the Plugin Directory and enable the authstack plugin. Load the shipped skill `implement-sso`. That skill includes the workflows, references, and prompts Codex uses to generate SAML and OIDC SSO code for your existing application. Done: `implement-sso` is available to Codex. 3. ## Generate the SSO implementation Use a structured prompt to direct Codex. A well-formed prompt helps Codex generate complete, production-ready SSO code that includes all required security components. Copy the following prompt into Codex: SSO implementation prompt ```md Guide the coding agent to add Scalekit SSO to my existing app — initialize ScalekitClient, generate an SSO authorization URL for a given organization, handle the SSO callback to validate and exchange the code for user identity, and integrate the SSO user into my existing session system. Code only. ``` When you submit this prompt, Codex loads the Modular SSO plugin from the authstack plugin, analyzes your existing application structure, generates Scalekit client initialization with environment credentials, creates an SSO authorization URL generator for organization-based routing, implements the SSO callback handler to validate and exchange the code for user identity, and integrates SSO user data into your existing session system. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 4. ## Verify the implementation After Codex completes, verify that all SSO components are properly configured: Check generated files: * Scalekit client initialization with environment credentials. You may need to set up a `.env` file with your Scalekit API credentials. * SSO authorization URL generation for organization-based routing * SSO callback handler that validates the authorization code and retrieves user identity * Integration logic that maps SSO user identity into your existing session system The SSO flow should redirect users to their organization’s identity provider, where they authenticate. Your application should then receive the callback, validate the code, extract the user’s identity, and create or update the user session accordingly. When users authenticate through SSO, your application receives verified identity claims from the identity provider. Verify that the SSO callback correctly maps user identity to your application’s user model and that the session is created with the appropriate access level. * GitHub Copilot CLI 1. ## Install the authstack plugin (recommended) Need to install GitHub Copilot CLI? See the [getting started guide](https://docs.github.com/en/copilot/how-tos/copilot-cli/cli-getting-started) — an active GitHub Copilot subscription is required. Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI installs the authstack plugin for GitHub Copilot. Then ask the agent to run the shipped skill `implement-sso`. Done: the command exits 0 and `implement-sso` is available. 2. ## Generate SSO implementation Use a structured prompt to direct GitHub Copilot. A well-formed prompt ensures the agent generates complete, production-ready SSO code that includes all required security components. Copy the following command into your terminal: Terminal ```bash copilot "Add Scalekit SSO to my existing app — initialize ScalekitClient, generate an SSO authorization URL for a given organization, handle the SSO callback to validate and exchange the code for user identity, and integrate the SSO user into my existing session system. Code only." ``` GitHub Copilot uses the Modular SSO plugin to analyze your existing application structure, generate Scalekit client initialization code, create an SSO authorization URL generator for organization-based routing, implement the SSO callback handler to validate and exchange the code for user identity, and integrate SSO user data into your existing session system. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your security requirements. The coding agent provides a foundation, but you must ensure it aligns with your application’s specific needs. 3. ## Verify the implementation After GitHub Copilot completes, verify that all SSO components are properly configured: Check generated files: * Scalekit client initialization with environment credentials (you may need to set up a `.env` file with your Scalekit API credentials) * SSO authorization URL generation for organization-based routing * SSO callback handler that validates the authorization code and retrieves user identity * Integration logic that maps SSO user identity into your existing session system The SSO flow should redirect users to their organization’s identity provider, where they authenticate. Your application should then receive the callback, validate the code, extract the user’s identity, and create or update the user session accordingly. When users authenticate through SSO, your application receives verified identity claims from the identity provider. Verify that the SSO callback correctly maps user identity to your application’s user model and that the session is created with the appropriate access level. * Cursor 1. ## Install the authstack plugin (recommended) Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` The CLI detects Cursor and installs the authstack plugin directly. 2. ## Reload and select plugins Restart Cursor (or run **Developer: Reload Window**), then open **Settings > Cursor Settings > Plugins**. Enable the Scalekit plugins you need. The shipped skills are `integrate-agentkit`, `implement-saaskit`, `add-mcp-oauth`, `implement-sso`, and `implement-scim`. Done: the plugin list shows the skill you need. 3. ## Generate the implementation Open Cursor’s chat panel with **Cmd+L** (macOS) or **Ctrl+L** (Windows/Linux) and paste in an implementation prompt from the feature page (or describe what you need in natural language). The installed Scalekit plugins provide the agent with accurate patterns. Review generated code Always review AI-generated authentication code before deployment. Verify that environment variables, token validation logic, and error handling match your application’s security requirements. 4. ## Verify the implementation After Cursor finishes generating code, confirm all authentication components are in place: * The Scalekit plugin appears in **Settings > Cursor Settings > Plugins** * Scalekit client initialized with your API credentials (set up a `.env` file with your Scalekit environment variables) * Authorization URL generation and callback handler * Session or token integration matching your application’s existing patterns * 40+ agents The authstack plugin works with 40+ AI agents. Skills are installed via the Scalekit CLI or the Vercel Skills CLI. The easiest way for most developers is: Terminal ```bash npx @scalekit-inc/cli setup ``` For repeated use, install globally: Terminal ```bash npm install -g @scalekit-inc/cli scalekit setup ``` Then choose the “Other agents” / skills option when prompted. You can also install the skills directly: 1. ## Install interactively Run the command with no flags to be guided through the available skills: Terminal ```bash npx skills add scalekit-inc/authstack ``` 2. ## Browse and install a specific skill Install the skill for your auth type (for example, MCP OAuth): Terminal ```bash # List all available skills npx skills add scalekit-inc/authstack --list # Install a specific skill npx skills add scalekit-inc/authstack --skill add-mcp-oauth ``` 3. ## Invoke the skill Varies by agent Each coding agent has its own behavior for invoking skills. In OpenCode, skills are invoked **automatically by the agent based on natural language** — no slash commands required. The agent has a list of available skills and their `description` fields in context. It reads your intent, matches it against those descriptions, and autonomously calls the skill tool to load the relevant `SKILL.md`. A clear, specific `description` in skill frontmatter is what the agent uses to decide which skill to invoke. **Flow in practice:** * You write a natural language message to the agent * The agent checks its context — it already sees `` with names and descriptions * If your request matches a skill’s purpose, the agent calls `skill("")` internally * The full `SKILL.md` content loads into context and the agent follows those instructions If your agent does not automatically pick up skills, you can run a command to load a skill and manually select Scalekit’s skills to load into context. Refer to your favorite coding agent’s documentation for how to invoke skills once they are installed. 4. ## Install all skills globally To add all Scalekit authentication skills to your agents: Terminal ```bash npx skills add scalekit-inc/authstack --all --global ``` This installs all AgentKit and SaaSKit skills. --- # DOCUMENT BOUNDARY --- # Scalekit CLI > Install and manage the authstack plugin for AI coding agents with the Scalekit CLI. The Scalekit CLI (`@scalekit-inc/cli`) installs the authstack plugin for your AI coding agents. Run one command and the CLI detects your active tools (Cursor, Claude Code, GitHub Copilot, Codex) and sets each one up automatically. ```bash 1 npm install -g @scalekit-inc/cli 2 scalekit setup ``` Running `setup` with no arguments launches an interactive wizard that detects your installed tools and installs the authstack plugin for each one. ## Target a specific tool [Section titled “Target a specific tool”](#target-a-specific-tool) Pass the tool name to skip the wizard and install directly: ```bash 1 scalekit setup cursor 2 scalekit setup claude # aliases: claude-code, cc 3 scalekit setup codex # alias: opencode 4 scalekit setup copilot # aliases: github-copilot, ghcp ``` ## Command reference [Section titled “Command reference”](#command-reference) ### `setup [tool]` [Section titled “setup \[tool\]”](#setup-tool) Installs the authstack plugin for one or all detected coding agents. | Argument / flag | Description | | --------------- | ------------------------------------------------------------------------------------------------------------------------ | | `[tool]` | Target a specific agent: `cursor`, `claude`, `codex`, `copilot` (and their aliases). Omit to run the interactive wizard. | | `-y`, `--yes` | Skip confirmation prompts. Useful in scripts. | | `--dry-run` | Print the commands that would run without executing them. | | `--skip-skills` | Skip installing generic Scalekit skills (installs the plugin only). | ### Supported tools [Section titled “Supported tools”](#supported-tools) | Tool | ID | Aliases | | ---------------- | --------- | ------------------------ | | Cursor | `cursor` | | | Claude Code | `claude` | `claude-code`, `cc` | | GitHub Copilot | `copilot` | `github-copilot`, `ghcp` | | Codex / OpenCode | `codex` | `opencode` | ### What gets installed [Section titled “What gets installed”](#what-gets-installed) For each detected tool, the CLI installs two kits from the authstack plugin: * **AgentKit** - skills for building agents with delegated auth, scoped permissions, and tool calls * **SaaSKit** - skills for adding SSO, SCIM, MFA, sessions, and API auth to SaaS apps For Cursor and Codex, the CLI downloads the plugin and copies it to the tool’s local plugin directory. For Claude Code and GitHub Copilot, it runs the tool’s native plugin marketplace commands. ## Start building [Section titled “Start building”](#start-building) After setup, tell your coding agent what you’re building. The authstack plugin routes you to the right skill. * Claude Code ```text 1 I want to add agent auth to my project. Help me get started with AgentKit. ``` ```text 1 Add enterprise SSO to my Next.js app using SaaSKit. ``` * Cursor ```text 1 I want to add agent auth to my project. Help me get started with AgentKit. ``` ```text 1 Add enterprise SSO to my Next.js app using SaaSKit. ``` * GitHub Copilot ```text 1 I want to add agent auth to my project. Help me get started with AgentKit. ``` ```text 1 Add enterprise SSO to my Next.js app using SaaSKit. ``` * Codex ```text 1 I want to add agent auth to my project. Help me get started with AgentKit. ``` ```text 1 Add enterprise SSO to my Next.js app using SaaSKit. ``` The authstack plugin picks up the prompt and routes to the right skill: AgentKit for agent auth, SaaSKit for app auth. --- # DOCUMENT BOUNDARY --- # Error handling > Catch and respond to invalid tokens, bad requests, missing resources, and rate limits on the Scalekit REST API. Catch and respond to invalid tokens, bad requests, missing resources, and rate limits. A failed REST call returns an HTTP status and a JSON body. Official SDKs raise typed exceptions for the same failures. Use the body, or the exception fields, to choose a response. For the endpoint catalog, open the [API reference](/apis/#description/overview). Product catalogs live at [SaaSKit APIs](/saaskit/apis/#description/overview) and [AgentKit APIs](/agentkit/apis/#description/overview). ## Read the error body [Section titled “Read the error body”](#read-the-error-body) | Field | Meaning | | --------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | `code` | gRPC (remote procedure call) status **number**. This is not the HTTP status. Example: `16` means Unauthenticated. | | `message` | Human-readable reason. Safe for logs. Do not show raw messages to end users. | | `details[].error_code` | Stable slug to switch on, such as `UNAUTHENTICATED`. | | `details[].validation_error_info` | Present on some `400` responses. Lists field violations (`field`, `description`, `constraint`). | | `details[].tool_error_info` | Present when a tool call fails. Includes `execution_id`, `tool_error_message`, and `tool_error_code`. | | `details[].help_info` | Optional documentation links when the server attaches them. | Scalekit does not return a request ID or a dashboard log URL in this envelope. 401 when the bearer token is missing ```json 1 { 2 "code": 16, 3 "message": "Token empty", 4 "details": [ 5 { 6 "@type": "type.googleapis.com/scalekit.v1.errdetails.ErrorInfo", 7 "error_code": "UNAUTHENTICATED" 8 } 9 ] 10 } ``` Switch on `details[].error_code`. Do not switch on `code` alone. ## HTTP status codes [Section titled “HTTP status codes”](#http-status-codes) * Codes in the `2xx` range mean success. * Codes in the `4xx` range mean the request failed given the data you sent. Fix the request. Do not retry the same payload, except for `429`. * Codes in the `5xx` range mean a server fault. Retry with backoff. Treat the result as unknown until a later call succeeds. | HTTP | Typical `error_code` | Meaning | | ------------- | ----------------------------------- | ------------------------------------- | | `200` / `201` | n/a | Success | | `400` | `INVALID_ARGUMENT`, `BAD_REQUEST` | Invalid request or validation failure | | `401` | `UNAUTHENTICATED` | Missing or invalid bearer token | | `403` | `PERMISSION_DENIED`, `FORBIDDEN` | Authenticated, but not allowed | | `404` | `NOT_FOUND`, `RESOURCE_NOT_FOUND` | Resource does not exist | | `409` | `RESOURCE_ALREADY_EXISTS` | Duplicate resource | | `429` | `RATE_LIMITED`, `TOO_MANY_REQUESTS` | Rate limit exceeded | | `500` | `INTERNAL_ERROR` | Server error | ## Catch exceptions [Section titled “Catch exceptions”](#catch-exceptions) SDKs translate non-success HTTP responses into exceptions. Catch the specific type first, then fall back to the base server exception. * Node.js catch-api-errors.ts ```ts 1 import { 2 ScalekitNotFoundException, 3 ScalekitUnauthorizedException, 4 ScalekitTooManyRequestsException, 5 ScalekitServerException, 6 } from '@scalekit-sdk/node' 7 8 try { 9 // Your Scalekit SDK call 10 await scalekit.organization.listOrganization({ pageSize: 30 }) 11 } catch (err) { 12 if (err instanceof ScalekitUnauthorizedException) { 13 // Get a new access token. Do not retry the same bearer token. 14 } else if (err instanceof ScalekitNotFoundException) { 15 // Create the resource or return not-found to the caller. 16 } else if (err instanceof ScalekitTooManyRequestsException) { 17 // Back off. Read err.errorCode: RATE_LIMITED vs TOOL_ERROR. 18 } else if (err instanceof ScalekitServerException) { 19 // Log err.message and err.errorCode. Retry only on 5xx or 429. 20 } else { 21 throw err 22 } 23 } ``` * Python catch\_api\_errors.py ```py 1 from scalekit.common.exceptions import ( 2 ScalekitNotFoundException, 3 ScalekitUnauthorizedException, 4 ScalekitTooManyRequestsException, 5 ScalekitServerException, 6 ) 7 8 try: 9 # Your Scalekit SDK call 10 scalekit_client.organization.list_organizations(page_size=30) 11 except ScalekitUnauthorizedException: 12 # Get a new access token. Do not retry the same bearer token. 13 pass 14 except ScalekitNotFoundException: 15 # Create the resource or return not-found to the caller. 16 pass 17 except ScalekitTooManyRequestsException as e: 18 # Back off. Read e.error_code: RATE_LIMITED vs TOOL_ERROR. 19 print(e.error_code, e.message) 20 except ScalekitServerException as e: 21 # Log e.message and e.error_code. Retry only on 5xx or 429. 22 print(e.error_code, e.http_status) ``` * Go catch\_api\_errors.go ```go 1 _, err := scalekitClient.Organization().ListOrganization(ctx, &scalekit.ListOrganizationOptions{ 2 PageSize: 30, 3 }) 4 if err != nil { 5 // Inspect the error. Retry only on HTTP 429 or 5xx. 6 // Do not retry the same payload on 400, 401, 403, 404, or 409. 7 log.Printf("scalekit API error: %v", err) 8 return err 9 } ``` * Java CatchApiErrors.java ```java 1 try { 2 scalekitClient.organizations().listOrganizations(30, ""); 3 } catch (ScalekitException error) { 4 // Inspect the error. Retry only on HTTP 429 or 5xx. 5 // Do not retry the same payload on 400, 401, 403, 404, or 409. 6 System.err.println(error.getMessage()); 7 } ``` Typed exception names and tool-specific types are listed on [AgentKit Node error handling](/agentkit/sdks/node/errors/) and [AgentKit Python error handling](/agentkit/sdks/python/errors/). ## Choose a response [Section titled “Choose a response”](#choose-a-response) | `error_code` | Problem | What to do | | ------------------------------------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | `UNAUTHENTICATED` | Missing header (`Token empty`), bad `Bearer` value (`Invalid Token`), or expired token (`token expired`) | Request a new token. Do not retry the same token. See [Authenticate with the Scalekit API](/guides/authenticate-scalekit-api/). | | `INVALID_ARGUMENT` / `BAD_REQUEST` | The request is malformed or fails validation | Fix the fields. Do not retry the same payload. | | `PERMISSION_DENIED` / `FORBIDDEN` | The caller is authenticated but not allowed | Change roles, scopes, or the target resource. | | `NOT_FOUND` / `RESOURCE_NOT_FOUND` | The resource does not exist | Create it, or return not-found to your user. | | `RESOURCE_ALREADY_EXISTS` | A create conflicts with an existing resource | Use the existing ID, or pick a new unique value. | | `RATE_LIMITED` / `TOO_MANY_REQUESTS` | A Scalekit service rejected the call | Back off, then retry. See [API rate limits](/reference/rate-limits/). | | `TOOL_ERROR` | A tool call failed | Read `tool_error_info.tool_error_code`. An inner `RATE_LIMITED` is the upstream provider. | | `INTERNAL_ERROR` | A server fault | Retry with backoff. Treat the result as unknown until a later call succeeds. | `/api/v1` accepts a bearer access token from client credentials. It does not accept an API key header. ## Validation errors [Section titled “Validation errors”](#validation-errors) Some `400` responses include `validation_error_info.field_violations`. Each violation names the field, a description, and the constraint that failed. The JSON below is an example of that shape. Example validation error shape ```json 1 { 2 "code": 3, 3 "message": "Validation error", 4 "details": [ 5 { 6 "@type": "type.googleapis.com/scalekit.v1.errdetails.ErrorInfo", 7 "error_code": "INVALID_ARGUMENT", 8 "validation_error_info": { 9 "field_violations": [ 10 { 11 "field": "page_size", 12 "description": "value must be less than or equal to 30", 13 "constraint": "lte" 14 } 15 ] 16 } 17 } 18 ] 19 } ``` ## Tool errors [Section titled “Tool errors”](#tool-errors) Tool execution sets the **outer** `error_code` to `TOOL_ERROR`. The inner slug is `tool_error_info.tool_error_code`. An upstream provider `429` still returns HTTP `429`. Upstream provider rate limit on a tool call ```json 1 { 2 "code": 8, 3 "message": "tool execution failed - rate limited", 4 "details": [ 5 { 6 "@type": "type.googleapis.com/scalekit.v1.errdetails.ErrorInfo", 7 "error_code": "TOOL_ERROR", 8 "tool_error_info": { 9 "execution_id": "exec_123", 10 "tool_error_message": "rate limit", 11 "tool_error_code": "RATE_LIMITED" 12 } 13 } 14 ] 15 } ``` Read the outer code first. Then read `tool_error_info.tool_error_code` when the outer code is `TOOL_ERROR`. ## Handle 429s [Section titled “Handle 429s”](#handle-429s) When a service exceeds its limit, Scalekit returns HTTP `429`. The response body uses the same error envelope. | Outer `error_code` | Meaning | | -------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `RATE_LIMITED` | A Scalekit service rejected the call | | `TOO_MANY_REQUESTS` | Email, one-time password (OTP), or time-based one-time password (TOTP) traffic hit a limit | | `TOOL_ERROR` with inner `tool_error_code` `RATE_LIMITED` | The upstream provider rate-limited the tool call | Back off and retry with exponential backoff. Do not retry immediately. Scalekit does not send a `Retry-After` header on 429 responses. Limits vary by service and account. For 429 handling in the SDKs, see [API rate limits](/reference/rate-limits/). ## Fix common 400s [Section titled “Fix common 400s”](#fix-common-400s) Some `400` `INVALID_ARGUMENT` responses come from list and lookup URLs. | Case | HTTP | `error_code` | Message | | ----------------------------------- | ----- | ------------------ | ---------------------------------------- | | Bad `page_token` | `400` | `INVALID_ARGUMENT` | `invalid page token` or `Invalid cursor` | | `:external` path plus an `id` query | `400` | `INVALID_ARGUMENT` | `ExternalId is required` | Fix the URL or the query. Do not retry the same request. For list parameters, see the operation in the [API reference](/apis/#description/overview). For external IDs, see [organization identifiers](/guides/external-ids-and-metadata/). --- # DOCUMENT BOUNDARY --- # Billing and usage > View your current plan, manage payment methods, and monitor your Scalekit usage. Manage your Scalekit subscription, view invoices, and monitor your usage from the billing section of the dashboard. ## Access billing [Section titled “Access billing”](#access-billing) Navigate to **Dashboard > Settings > Billing** to view your billing information and manage your subscription. ## Current plan [Section titled “Current plan”](#current-plan) View your current subscription plan, including: * **Plan name** - Your current Scalekit plan * **Monthly active users** - Number of unique users who authenticated this month * **Usage limit** - Maximum number of active users included in your plan * **Renewal date** - When your current billing period ends ## Usage metrics [Section titled “Usage metrics”](#usage-metrics) Track key usage metrics to understand your authentication patterns: | Metric | Description | | ------------------------------ | ------------------------------------------------------- | | **Monthly Active Users (MAU)** | Unique users who authenticate at least once per month | | **Total Organizations** | Number of organizations created across all environments | | **Authentications** | Total number of successful authentication attempts | | **SSO Logins** | Number of logins through enterprise SSO connections | | **Social Logins** | Number of logins through social identity providers | ## Payment methods [Section titled “Payment methods”](#payment-methods) Manage your payment methods for subscription billing: 1. Navigate to **Dashboard > Settings > Billing** 2. Click **Payment methods** in the sidebar 3. Click **Add payment method** 4. Enter your card details or use a saved payment method ### Update payment method [Section titled “Update payment method”](#update-payment-method) To change your default payment method: 1. Click on the payment method card 2. Click **Make default** to set it as your primary payment method 3. Click **Remove** to delete a payment method Keep payment details current Ensure your payment method information is up to date to prevent service interruption. Expired cards may cause authentication failures. ## Invoices [Section titled “Invoices”](#invoices) View and download your invoices for each billing period: 1. Navigate to **Dashboard > Settings > Billing** 2. Click **Invoices** in the sidebar 3. Click on any invoice to view details 4. Click **Download PDF** to save a copy Invoices include a detailed breakdown of your charges, including base subscription fees and any overage charges. ## Upgrade or downgrade plans [Section titled “Upgrade or downgrade plans”](#upgrade-or-downgrade-plans) Change your plan based on your usage needs: 1. Navigate to **Dashboard > Settings > Billing** 2. Click **Change plan** 3. Select a new plan tier 4. Review the changes and confirm Plan changes take effect immediately. Pro-rated charges or credits apply based on your billing cycle. ## Set up alerts [Section titled “Set up alerts”](#set-up-alerts) Configure usage alerts to notify you when approaching your plan limits: 1. Navigate to **Dashboard > Settings > Billing** 2. Click **Usage alerts** in the sidebar 3. Set thresholds for monthly active users 4. Enter email addresses to receive alerts --- # DOCUMENT BOUNDARY --- # Manage environments > Configure development, staging, and production environments, and choose a US or EU region for data residency. Scalekit supports multiple environments to help you manage your application development lifecycle. Keep your development, staging, and production configurations separate while maintaining consistent authentication behavior. Environments live inside a workspace, and the workspace region (US or EU) is fixed at signup. ## Environment types [Section titled “Environment types”](#environment-types) Scalekit provides three default environments: | Environment | Purpose | | --------------- | ------------------------------------------------------------- | | **Development** | Local development and testing with relaxed security policies | | **Staging** | Pre-production testing that mirrors production configuration | | **Production** | Live environment with strict security policies and monitoring | ## Choose a region (US or EU) [Section titled “Choose a region (US or EU)”](#choose-a-region-us-or-eu) Scalekit runs two fully isolated regional deployments: **United States (US)** and **European Union (EU)**. Choose the region when you create the workspace. You cannot change the region later or migrate data between regions. ### How regional isolation works [Section titled “How regional isolation works”](#how-regional-isolation-works) The EU deployment is a separate infrastructure stack: dedicated GCP capacity in `europe-west3` (Frankfurt), separate databases, and separate authentication data. Customer data does not cross regional boundaries. Use the EU region when you need EU customer data hosted natively in the EU for GDPR data residency. Region is a one-time choice A US workspace cannot become an EU workspace, and the reverse is also true. If you signed up in the wrong region, create a new workspace in the correct region and reconfigure your integration there. Scalekit can delete the incorrect workspace on request after you migrate. ### Create an EU workspace [Section titled “Create an EU workspace”](#create-an-eu-workspace) Sign up on the EU cluster: 1. Go to [auth.eu.scalekit.com/a/auth/signup](https://auth.eu.scalekit.com/a/auth/signup) 2. Create your workspace as usual The EU workspace includes its own **Development** and **Production** environments, the same layout as a US workspace. ### Billing for EU environments [Section titled “Billing for EU environments”](#billing-for-eu-environments) EU data residency is a **$99/month add-on per production environment**, billed separately from any US workspace. The add-on applies to Auth for SaaS (Modular SSO, MCP Auth) and AgentKit. Other per-environment add-ons, such as **Customization Pro** (custom domain, branding removal, custom email templates), are also billed per region. Running Customization Pro on both a US and an EU production environment bills the add-on twice. Add a payment method under **Workspace Settings → Billing** in the EU workspace so the add-on and usage-based charges succeed. See [Billing and usage](/dev-kit/guides/dashboard/billing/) for payment methods and plan details. ## Access environment settings [Section titled “Access environment settings”](#access-environment-settings) Navigate to **Dashboard > Settings > Environments** to view and manage your environments. Each environment has its own: * Environment ID and URL * API credentials (client ID and secret) * Redirect URLs * Webhook endpoints * Authentication method configurations ## Switch between environments [Section titled “Switch between environments”](#switch-between-environments) Use the environment selector in the top-right corner of the dashboard to switch between environments. Verify your environment Always confirm you’re working in the correct environment before making configuration changes. The dashboard displays the current environment name in the header. ## Configure environment-specific settings [Section titled “Configure environment-specific settings”](#configure-environment-specific-settings) ### Redirect URLs [Section titled “Redirect URLs”](#redirect-urls) Each environment requires its own set of redirect URLs. Configure the appropriate URLs for your application in each environment: * **Development**: `http://localhost:3000/auth/callback` * **Staging**: `https://staging.yourapp.com/auth/callback` * **Production**: `https://yourapp.com/auth/callback` ### API credentials [Section titled “API credentials”](#api-credentials) Each environment uses unique API credentials. Store credentials securely using environment variables: ```bash 1 # Development 2 SCALEKIT_ENVIRONMENT_ID=dev_env_123 3 SCALEKIT_CLIENT_ID=dev_client_abc 4 SCALEKIT_CLIENT_SECRET=dev_secret_xyz 5 6 # Production 7 SCALEKIT_ENVIRONMENT_ID=prod_env_456 8 SCALEKIT_CLIENT_ID=prod_client_def 9 SCALEKIT_CLIENT_SECRET=prod_secret_uvw ``` ### Webhook endpoints [Section titled “Webhook endpoints”](#webhook-endpoints) Configure different webhook endpoints for each environment to test webhook delivery in staging before enabling in production. ## Environment best practices [Section titled “Environment best practices”](#environment-best-practices) * **Never use production credentials in development** * **Test all changes in staging before deploying to production** * **Use environment-specific API endpoints** * **Monitor logs separately for each environment** * **Keep webhook configurations synchronized across environments** --- # DOCUMENT BOUNDARY --- # Manage team members > Invite team members to your Scalekit organization and manage their access and permissions. Scalekit allows you to collaborate with your team by inviting members to your organization. Control who can access your dashboard and what actions they can perform based on their role. ## Access team management [Section titled “Access team management”](#access-team-management) Navigate to **Dashboard > Settings > Team** to view and manage team members. ## Team member roles [Section titled “Team member roles”](#team-member-roles) Scalekit supports two roles with different permission levels: | Role | Permissions | | ---------- | ------------------------------------------------------------------------------------------------- | | **Owner** | Full access to all settings, billing, and team management. Can invite and remove members. | | **Member** | View and manage authentication configurations, but cannot access billing or remove other members. | At least one owner required Your organization must have at least one owner at all times. The last owner cannot leave or change their role. ## Invite team members [Section titled “Invite team members”](#invite-team-members) 1. Navigate to **Dashboard > Settings > Team** 2. Click **Invite member** 3. Enter the team member’s email address 4. Select their role (Owner or Member) 5. Click **Send invite** The invited member receives an email with a link to join your organization. They must sign in with their existing Scalekit account or create a new account to accept the invitation. ## Manage pending invitations [Section titled “Manage pending invitations”](#manage-pending-invitations) View and manage pending invitations from the Team settings page: * **Resend invite** - Send a reminder email for pending invitations * **Cancel invite** - Revoke a pending invitation before it’s accepted ## Change member roles [Section titled “Change member roles”](#change-member-roles) 1. Navigate to **Dashboard > Settings > Team** 2. Find the team member whose role you want to change 3. Click the **Role** dropdown next to their name 4. Select the new role ## Remove team members [Section titled “Remove team members”](#remove-team-members) 1. Navigate to **Dashboard > Settings > Team** 2. Find the team member you want to remove 3. Click the **Remove** button next to their name 4. Confirm the removal Removed team members immediately lose access to your organization’s dashboard and configurations. ## Team member activity [Section titled “Team member activity”](#team-member-activity) View recent activity for each team member, including: * When they joined the organization * Recent configuration changes they made * Last sign-in time ## Security best practices [Section titled “Security best practices”](#security-best-practices) * **Use the principle of least privilege** - Grant Member role by default * **Regularly review team access** - Remove members who no longer need access * **Monitor audit logs** - Track team member activity in the auth logs * **Enable SSO for team access** - Require SSO authentication for dashboard access --- # DOCUMENT BOUNDARY --- # SCIM Simulator > Test your SCIM integration locally with the Scalekit SCIM Simulator Coming soon --- # DOCUMENT BOUNDARY --- # SDKs > Ready-to-use SDKs for Node.js, Python, Go, and Java to integrate Scalekit into your app * [Node.jsv2.15.0](/saaskit/sdks/node/) [npm install @scalekit-sdk/node](/saaskit/sdks/node/) [Full-featured, TypeScript-friendly SDK for modern Node.js based applications](/saaskit/sdks/node/) [Updated 5 days agoInstall→](/saaskit/sdks/node/) * [Expressv2.15.0](/saaskit/sdks/express/) [npm install @scalekit-sdk/node express](/saaskit/sdks/express/) [Session middleware for Express. Hosted login, encrypted cookie, token refresh.](/saaskit/sdks/express/) [Updated 5 days agoInstall→](/saaskit/sdks/express/) * [Next.jsv2.15.0](/saaskit/sdks/nextjs/) [npm install @scalekit-sdk/node](/saaskit/sdks/nextjs/) [Session middleware for the Next.js App Router, including Edge Runtime.](/saaskit/sdks/nextjs/) [Updated 5 days agoInstall→](/saaskit/sdks/nextjs/) * [Pythonv2.19.1](/saaskit/sdks/python/) [pip install scalekit-sdk-python](/saaskit/sdks/python/) [Async-first design with complete type hints and Pydantic validation](/saaskit/sdks/python/) [Updated 5 days agoInstall→](/saaskit/sdks/python/) * [Flaskv2.19.1](/saaskit/sdks/flask/) [pip install "scalekit-sdk-python\[flask\]"](/saaskit/sdks/flask/) [Session middleware for Flask. Hosted login, encrypted cookie, token refresh.](/saaskit/sdks/flask/) [Updated 5 days agoInstall→](/saaskit/sdks/flask/) * [FastAPIv2.19.1](/saaskit/sdks/fastapi/) [pip install "scalekit-sdk-python\[fastapi\]"](/saaskit/sdks/fastapi/) [Session middleware for FastAPI. Protect routes with Depends().](/saaskit/sdks/fastapi/) [Updated 5 days agoInstall→](/saaskit/sdks/fastapi/) * [Djangov2.19.1](/saaskit/sdks/django/) [pip install "scalekit-sdk-python\[django\]"](/saaskit/sdks/django/) [Session middleware for Django. Settings-based config and login\_required.](/saaskit/sdks/django/) [Updated 5 days agoInstall→](/saaskit/sdks/django/) * [Gov2.8.0](/saaskit/sdks/go/) [go get github.com/scalekit-inc/scalekit-sdk-go](/saaskit/sdks/go/) [Zero-dependency, idiomatic Go SDK for high-performance services](/saaskit/sdks/go/) [Updated 1 month agoInstall→](/saaskit/sdks/go/) * [Javav2.4.0](/saaskit/sdks/java/) [Maven Central: com.scalekit:scalekit-sdk-java](/saaskit/sdks/java/) [Enterprise-ready SDK with seamless Spring Boot integration](/saaskit/sdks/java/) [Updated 5 days agoInstall→](/saaskit/sdks/java/) * [Expo](/sdks/expo/) [npx expo install @scalekit-sdk/expo](/sdks/expo/) [Official Expo SDK with React Hooks for enterprise-ready mobile authentication](/sdks/expo/) [Install→](/sdks/expo/) * [iOS](/sdks/ios/) [Swift Package Manager: ScalekitSDK](/sdks/ios/) [Native iOS SDK for enterprise-ready mobile authentication via AppAuth](/sdks/ios/) [Install→](/sdks/ios/) --- # DOCUMENT BOUNDARY --- # Dryrun > Try your authentication flows locally before any integration code is written Use `npx @scalekit-sdk/dryrun` when you want to confirm your Scalekit authentication configuration works end-to-end before implementing auth integration into your app. Dryrun command executes a complete authentication flow locally - spinning up a server, opening your browser, and displaying the authenticated user’s profile and tokens, so you can catch configuration errors early. Works with Full Stack Authentication and Modular SSO. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) Before running Dryrun, ensure you have: * **Node.js 20 or higher** installed locally. * **A Scalekit environment** with an OAuth client configured. * **A redirect URI** (`http://localhost:12456/auth/callback`) added in the Scalekit Dashboard under **Authentication > Redirect URIs**. ## Run Dryrun [Section titled “Run Dryrun”](#run-dryrun) From any directory: Terminal ```bash # Refer to prerequisites before running the command npx @scalekit-sdk/dryrun \ --env_url= \ --client_id= \ [--mode=] \ [--organization_id=] ``` | Option | Description | | ------------------- | ----------------------------------------------------------------------------------- | | `--env_url` | Scalekit environment URL, for example `https://env-abc123.scalekit.cloud`. Required | | `--client_id` | OAuth client ID from the Scalekit Dashboard (starts with `skc_`). Required | | `--mode` | `fsa` for full-stack auth, `sso` for SSO. Defaults to `fsa`. Optional | | `--organization_id` | Organization ID to authenticate against when `--mode=sso`. Required (SSO only) | | `--help` | Show CLI usage help. Optional | Local testing only Dryrun is designed for **local testing only**: * It runs entirely on `localhost` and does not expose any public endpoints. * It does not persist tokens or credentials after the process exits. * The CLI stops when you press `Ctrl+C`, which shuts down the local server. Use this tool only in trusted local environments and never expose the local callback URL to the internet. ## Review authentication results [Section titled “Review authentication results”](#review-authentication-results) After successful authentication, the browser shows a local dashboard with: * **User profile**: Name, email, avatar (when available). * **ID token claims**: All claims returned in the ID token. * **Token details**: A view of the raw token response. ![User profile details screenshot](/.netlify/images?url=_astro%2Fuser-profile-details.C55W6Ini.png\&w=2922\&h=1854\&dpl=6aaa70ad2ea7b40008ad2afd) Use this view to confirm: * The correct user is returned for your test login. * Claims such as `email`, `sub`, and any custom claims are present as expected. * The flow works for both `fsa` and `sso` modes when configured. ## Common error scenarios [Section titled “Common error scenarios”](#common-error-scenarios) --- # DOCUMENT BOUNDARY --- # SSO simulator > Test SSO flows end to end using Scalekit’s built-in IdP simulator and a pre-configured test organization. Scalekit provides an **SSO simulator** so you can test SSO flows before you connect to real enterprise identity providers. You use it when you are implementing SSO with Scalekit and want to verify your application’s behavior end to end. Without the simulator, you often need to configure multiple providers—such as Microsoft Entra ID, PingIdentity, and Okta—and create test tenants and users just to prove that your SSO flow works. Instead, the SSO simulator lets you trigger the authentication flow with test email domains like `@example.com` and verify how your application handles successful logins and failures, without doing any external IdP configuration. Before you use the SSO simulator, make sure you have: * SSO flow integrated in your app with Scalekit. For example, you have completed setup that generates an authorization URL and handles the callback either with [Modular SSO](/authenticate/sso/add-modular-sso) or [Full stack Authentication](/authenticate/auth-methods/enterprise-sso). * Access to the [Scalekit Dashboard](https://app.scalekit.com) for viewing organizations and connection details. Your development environment includes a **Test Organization** that has connection already setup to the SSO simulator. This organization is safe to use for SSO testing and does not affect real customers. 1. **Locate the test organization** Open **Dashboard → Organizations** and look for an entry named **Test Organization**. The details page shows the test organization’s identifier (for example, `org_32656XXXXXX0438`) and any connected SSO integrations. ![Test Organization](/.netlify/images?url=_astro%2F2.CCYEcEtj.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) 2. **Copy the organization ID** From the **Test Organization** details page, copy the **Organization ID**. You pass this value to the SDK when you generate an SSO authorization URL. * Node.js Express.js ```javascript 1 const options = { 2 organizationId: 'org_32656XXXXXX0438', 3 } 4 5 const authorizationUrl = await scalekit.getAuthorizationUrl( 6 'https://your-app.example.com/auth/callback', 7 options, 8 ) ``` * Python Flask ```python 1 options = { 2 "organizationId": "org_32656XXXXXX0438", 3 } 4 5 authorization_url = scalekit_client.get_authorization_url( 6 "https://your-app.example.com/auth/callback", 7 options, 8 ) ``` * Go Gin ```go 1 options := scalekit.AuthorizationUrlOptions{ 2 OrganizationId: "org_32656XXXXXX0438", 3 } 4 5 authorizationURL, err := scalekitClient.GetAuthorizationUrl( 6 "https://your-app.example.com/auth/callback", 7 options, 8 ) ``` * Java Spring Boot ```java 1 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 2 options.setOrganizationId("org_32656XXXXXX0438"); 3 4 URI authorizationUrl = scalekitClient 5 .authentication() 6 .getAuthorizationUrl("https://your-app.example.com/auth/callback", options); ``` * Direct URL (no SDK) Authorization URL ```sh /oauth/authorize? response_type=code& client_id=& redirect_uri=& scope=openid%20profile%20email& organization_id=org_32656XXXXXX0438 ``` 3. **Simulate a SSO login** Generated authorization URL redirects the users to SSO simulator. 1. Select **User login via SSO** from the dropdown menu 2. Enter test user details (email, name, etc.) to simulate authentication 3. Click **Submit** to complete the simulation ![SSO Simulator form](/.netlify/images?url=_astro%2F2.1.BEM1Vo-J.png\&w=2646\&h=1652\&dpl=6aaa70ad2ea7b40008ad2afd) After submitting the form, your application receives an `idToken` containing the user details you entered: ![ID token response](/.netlify/images?url=_astro%2F2.2.tePTMu6U.png\&w=2182\&h=1146\&dpl=6aaa70ad2ea7b40008ad2afd) ### Full stack authentication vs modular SSO [Section titled “Full stack authentication vs modular SSO”](#full-stack-authentication-vs-modular-sso) How you reach the SSO simulator depends on how you use Scalekit: * **Modular SSO:** You can route users to the SSO simulator by including `login_hint=name@example.com` (or `organization_id=`) in the authorization URL. You are not limited to passing only the organization ID. * **Full stack authentication:** You do not need to pass any parameters when creating the authorization URL. Redirect users to Scalekit’s hosted login page; when they enter an email with a domain such as `example.com` or `example.org`, the login screen automatically sends them to the SSO simulator. --- # DOCUMENT BOUNDARY --- # Use Scalekit credentials > Use Scalekit-managed test accounts to validate social logins and agent tool connections without configuring your own provider credentials. Scalekit provides development environments that let you test your authentication flows end to end. Flows that depend on third-party providers, such as social logins with Google or tool connections like HubSpot, normally require you to configure your own OAuth apps and test with real user accounts. Configuring each provider and managing test accounts is time-consuming. Scalekit credentials let you use provider-specific test accounts that Scalekit manages for you, so you can skip most of the provider setup and focus on your application logic. Scalekit manages the OAuth apps and test accounts for supported providers. When you enable Scalekit credentials for a connection, Scalekit: * Uses its own client IDs, secrets, and test accounts for that provider * Handles the provider-side login or authorization on your behalf * Returns tokens and user data to your application as if a real user had completed the flow Your application receives the same type of responses it would receive from a fully configured production integration, but without requiring you to manage provider configuration during development. ## Use Scalekit credentials for agent tool connections [Section titled “Use Scalekit credentials for agent tool connections”](#use-scalekit-credentials-for-agent-tool-connections) To use Scalekit credentials for agent tool connections: * Open **Scalekit Dashboard → Agent tool connections** * Choose a tool connection (for example, HubSpot) * Select **Use Scalekit credentials** The next tool invocation for that connection automatically uses the Scalekit-managed credentials and lets you make tool calls without configuring your own OAuth app or test account. ## Use Scalekit credentials for social connections [Section titled “Use Scalekit credentials for social connections”](#use-scalekit-credentials-for-social-connections) To use Scalekit credentials for social login providers: * Open **Scalekit Dashboard → Authentication → Auth methods → Social login** * Choose a social provider (for example, Google or Microsoft) * Select **Use Scalekit credentials** The next social login for that provider automatically uses the Scalekit-managed credentials and lets you complete login flows without maintaining separate test identities or local OAuth configurations. ![Scalekit dashboard Social Login settings for Google with "Use Scalekit credentials" selected under OAuth Configuration](/.netlify/images?url=_astro%2F01.BGnueJDk.png\&w=1970\&h=915\&dpl=6aaa70ad2ea7b40008ad2afd) --- # DOCUMENT BOUNDARY --- # Admin portal > Implement Scalekit's self-serve admin portal to let customers configure SCIM via a shareable link or embedded iframe The admin portal provides a self-serve interface for customers to configure single sign-on (SSO) and directory sync (SCIM) connections. Scalekit hosts the portal and provides two integration methods: generate a shareable link through the dashboard or programmatically embed the portal in your application using an iframe. This guide shows you how to implement both integration methods. For the broader customer onboarding workflow, see [Onboard enterprise customers](/sso/guides/onboard-enterprise-customers/). ## Generate shareable portal link No-code Generate a shareable link through the Scalekit dashboard to give customers access to the admin portal. This method requires no code and is ideal for quick setup. ### Create the portal link 1. Log in to the [Scalekit dashboard](https://app.scalekit.com) 2. Navigate to **Dashboard > Organizations** 3. Select the target organization 4. Click **Generate link** to create a shareable admin portal link The generated link follows this format: Portal link example ```http https://your-app.scalekit.dev/magicLink/2cbe56de-eec4-41d2-abed-90a5b82286c4_p ``` ### Link properties | Property | Details | | -------------- | ------------------------------------------------------------------------------- | | **Expiration** | Links expire after 7 days | | **Revocation** | Revoke links anytime from the dashboard | | **Sharing** | Share via email, Slack, or any preferred channel | | **Security** | Anyone with the link can view and update the organization’s connection settings | Security consideration Treat portal links as sensitive credentials. Anyone with the link can view and modify the organization’s SSO and SCIM configuration. ## Embed the admin portal Programmatic Embed the admin portal directly in your application using an iframe. This allows customers to configure SSO and SCIM without leaving your app, creating a seamless experience within your settings or admin interface. The portal link must be generated programmatically on each page load for security. Each generated link is single-use and expires after 1 minute, though once loaded, the session remains active for up to 6 hours. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` ### Generate portal link Use the Scalekit SDK to generate a unique, embeddable admin portal link for an organization. Call this API endpoint each time you render the page containing the iframe. * Node.js Express.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new Scalekit( 4 process.env.SCALEKIT_ENVIRONMENT_URL, 5 process.env.SCALEKIT_CLIENT_ID, 6 process.env.SCALEKIT_CLIENT_SECRET, 7 ); 8 9 async function generatePortalLink(organizationId) { 10 const link = await scalekit.organization.generatePortalLink(organizationId); 11 return link.location; // Use as iframe src 12 } ``` * Python Flask ```python 1 from scalekit import Scalekit 2 import os 3 4 scalekit_client = Scalekit( 5 environment_url=os.environ.get("SCALEKIT_ENVIRONMENT_URL"), 6 client_id=os.environ.get("SCALEKIT_CLIENT_ID"), 7 client_secret=os.environ.get("SCALEKIT_CLIENT_SECRET") 8 ) 9 10 def generate_portal_link(organization_id): 11 link = scalekit_client.organization.generate_portal_link(organization_id) 12 return link.location # Use as iframe src ``` * Go Gin ```go 1 import ( 2 "context" 3 "os" 4 5 "github.com/scalekit/sdk-go" 6 ) 7 8 scalekitClient := scalekit.New( 9 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 10 os.Getenv("SCALEKIT_CLIENT_ID"), 11 os.Getenv("SCALEKIT_CLIENT_SECRET"), 12 ) 13 14 func generatePortalLink(organizationID string) (string, error) { 15 ctx := context.Background() 16 link, err := scalekitClient.Organization().GeneratePortalLink(ctx, organizationID) 17 if err != nil { 18 return "", err 19 } 20 return link.Location, nil // Use as iframe src 21 } ``` * Java Spring Boot ```java 1 import com.scalekit.client.Scalekit; 2 import com.scalekit.client.models.Link; 3 import com.scalekit.client.models.Feature; 4 import java.util.Arrays; 5 6 Scalekit scalekitClient = new Scalekit( 7 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 8 System.getenv("SCALEKIT_CLIENT_ID"), 9 System.getenv("SCALEKIT_CLIENT_SECRET") 10 ); 11 12 public String generatePortalLink(String organizationId) { 13 Link portalLink = scalekitClient.organizations() 14 .generatePortalLink(organizationId, Arrays.asList(Feature.sso, Feature.dir_sync, Feature.domain_verification)); 15 return portalLink.getLocation(); // Use as iframe src 16 } ``` The API returns a JSON object with the portal link. Use the `location` property as the iframe `src`: API response ```json { "id": "8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "location": "https://random-subdomain.scalekit.dev/magicLink/8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "expireTime": "2024-10-03T13:35:50.563013Z" } ``` Embed portal in iframe ```html ``` Embed the portal in your application’s settings or admin section where customers manage authentication configuration. ### Configuration and session | Setting | Requirement | | --------------------- | ----------------------------------------------------------------------------------------------------- | | **Redirect URI** | Add your application domain at **Dashboard > Authentication > Redirect URLs > Allowed callback URLs** | | **iframe attributes** | Include `allow="clipboard-write"` for copy-paste functionality | | **Dimensions** | Minimum recommended height: 600px | | **Link expiration** | Generated links expire after 1 minute if not loaded | | **Session duration** | Portal session remains active for up to 6 hours once loaded | | **Single-use** | Each generated link can only be used once to initialize a session | ## Customize the admin portal Match the admin portal to your brand identity. Configure branding at **Dashboard > Settings > Branding**: | Option | Description | | ---------------- | --------------------------------------------------------- | | **Logo** | Upload your company logo (displayed in the portal header) | | **Accent color** | Set the primary color to match your brand palette | | **Favicon** | Provide a custom favicon for browser tabs | For additional customization options including custom domains, see the [Custom domain guide](/guides/custom-domain/). [SSO integrations](/guides/integrations/sso-integrations/)Administrator guides to set up SSO integrations [Portal events](/reference/admin-portal/ui-events/)Listen to the browser events emitted from the embedded admin portal --- # DOCUMENT BOUNDARY --- # Explore sample apps > Explore sample apps for building an Admin Portal and integrating webhooks. Find code examples to streamline SCIM provisioning and user management. Whether you’re building an Admin Portal or implementing webhooks, we’ve got you covered with practical samples and upcoming language-specific examples. ### Admin Portal [Section titled “Admin Portal”](#admin-portal) Our [admin portal](/guides/admin-portal) sample demonstrates key features and functionality for administrative users. It showcase how the admin portal can be integrated with your application to provide efficient and seamless way for IT admins to configure SCIM Provisioning. [Check out the sample app](https://github.com/scalekit-developers/nodejs-example-apps/tree/main/embed-admin-portal-sample) ### NextJS webhook demo [Section titled “NextJS webhook demo”](#nextjs-webhook-demo) This sample application built with NextJS illustrates the implementation and usage of webhooks in a real-world scenario. It provides a practical example of how to integrate webhook functionality into your projects. [Check out the sample app](https://github.com/scalekit-developers/nextjs-example-apps/tree/main/webhook-events) --- # DOCUMENT BOUNDARY --- # SCIM provisioning code samples > Code samples demonstrating SCIM provisioning examples and integration patterns for user and group management ### [Handle SCIM webhooks](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/webhook-events) [Process SCIM directory updates in Next.js. Example shows how to verify webhook signatures and sync user data](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/webhook-events) ### [Embed admin portal](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) [Securely embed the Scalekit Admin Portal via iframe. Node.js example for managing directory sync and organizational settings](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) --- # DOCUMENT BOUNDARY --- # Automatically assign roles > Automatically assign roles to users in your application by mapping directory provider groups to application roles using Scalekit Manually assigning roles to users in your application consumes time and creates room for errors for your customers (usually, administrators). Scalekit monitors role changes in connected directories and notifies your application through webhooks. You use the event payload to keep user roles in your application in sync with directory groups in near real time. ## How group-based role assignment works [Section titled “How group-based role assignment works”](#how-group-based-role-assignment-works) Organization administrators commonly manage varying access levels by grouping users in their directory. For example, to manage access levels to GitHub, they create groups for each role and assign users to those groups. In this case a **Maintainer** group includes all the users who should have maintainer access to the repository. This enables your application to take necessary actions such as creating or modifying user roles as directed by the organization’s administrators. When an administrator deletes a group from the directory, Scalekit removes that group from every member’s group list and recalculates each member’s role from their remaining group memberships. This happens even for users who belong to multiple mapped groups, so deleting one group never leaves a stale role or membership behind for a user who is still a member of other groups. ## Set up automatic role assignment [Section titled “Set up automatic role assignment”](#set-up-automatic-role-assignment) To enable administrators to map directory groups to roles in your app, complete these steps: 1. Open the Scalekit dashboard. 2. Go to **Roles & Permissions**. 3. Use the **Roles** and **Permissions** sections to configure your application’s authorization model. 4. Register your app’s roles and permissions so Scalekit can reference them in mappings and webhook events. Select **Add role** to create a new role. Choose clear display names and descriptions for your roles. This helps customers understand and align the roles with the access levels they already maintain in their directory. ![Scalekit roles configuration page showing list of application roles](/.netlify/images?url=_astro%2Fadd-role-page.CgXDutLo.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) The roles page lists a couple of sample roles by default. You can edit or remove these and add new roles that match your application’s authorization model. ![Scalekit roles list showing default and custom roles](/.netlify/images?url=_astro%2Fdefault-roles.DC1cIuRF.png\&w=3200\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) Specify the default roles your app wants to assign to the organization creator and to members who belong to the same organization. All added roles are available for you to select as default roles. ![Scalekit default roles configuration for creators and members](/.netlify/images?url=_astro%2Fdefault-roles.DC1cIuRF.png\&w=3200\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) ### Connect organization groups to app roles [Section titled “Connect organization groups to app roles”](#connect-organization-groups-to-app-roles) After you create roles, they represent the roles in your app that you want directory groups to control. Users receive role assignments in your app based on the groups they belong to in their directory. You can set up this mapping in two ways: 1. Configure mappings in the Scalekit dashboard on behalf of organization administrators. Select the organization and go to the **SCIM provisioning** tab. 2. Share the [admin portal link](/guides/admin-portal#generate-shareable-portal-link) with organization administrators so they can configure the mappings themselves. Scalekit automatically displays mapping options in both the Scalekit dashboard and the admin portal. This allows administrators to connect organization groups to app roles without custom logic in your application. ![Mapping directory groups to application roles in Scalekit](/.netlify/images?url=_astro%2F2.CqGIp9Zu.png\&w=2010\&h=1092\&dpl=6aaa70ad2ea7b40008ad2afd) ## Handle role update events [Section titled “Handle role update events”](#handle-role-update-events) Scalekit continuously monitors updates from your customers’ directory providers and sends event payloads to your application through a registered webhook endpoint. To set up these endpoints and manage subscriptions, use the **Webhooks** option in the Scalekit dashboard. Listen for the `organization.directory.user_updated` event to determine a user’s roles from the payload. Scalekit automatically includes role information that is relevant to your app, based on the roles you configured in the Scalekit dashboard. * Node.js Create a webhook endpoint for role updates ```javascript 1 // Webhook endpoint to receive directory role updates 2 app.post('/webhook', async (req, res) => { 3 // Extract event data from the webhook payload 4 const event = req.body; 5 const { email, roles } = event.data; 6 7 console.log('Received directory role update for:', email); 8 9 // Extract role_name from the roles array, if present 10 const roleName = Array.isArray(roles) && roles.length > 0 ? roles[0].role_name : null; 11 console.log('Role name received:', roleName); 12 13 // Business logic: update user role and permissions in your app 14 if (roleName) { 15 await assignRole(roleName, email); 16 console.log('Updated access for user:', email); 17 } 18 19 res.status(201).json({ 20 message: 'Role processed', 21 }); 22 }); ``` * Python Create a webhook endpoint for role updates ```python 1 import json 2 from fastapi import FastAPI, Request 3 from fastapi.responses import JSONResponse 4 5 app = FastAPI() 6 7 8 @app.post("/webhook") 9 async def api_webhook(request: Request): 10 # Parse request body from the webhook payload 11 body = await request.body() 12 payload = json.loads(body.decode()) 13 14 # Extract user data 15 user_roles = payload["data"].get("roles", []) 16 user_email = payload["data"].get("email") 17 18 print("User roles:", user_roles) 19 print("User email:", user_email) 20 21 # Business logic: assign role in your app 22 if user_roles and user_email: 23 await assign_role(user_roles[0], user_email) 24 25 return JSONResponse( 26 status_code=201, 27 content={"message": "Role processed"}, 28 ) ``` * Java Create a webhook endpoint for role updates ```java 1 @PostMapping("/webhook") 2 public ResponseEntity> webhook(@RequestBody String body, @RequestHeader Map headers) { 3 ObjectMapper mapper = new ObjectMapper(); 4 5 try { 6 JsonNode node = mapper.readTree(body); 7 JsonNode roles = node.get("data").get("roles"); 8 String email = node.get("data").get("email").asText(); 9 10 System.out.println("Roles: " + roles); 11 System.out.println("Email: " + email); 12 13 // TODO: Add role to user in your application 14 15 Map responseBody = new HashMap<>(); 16 responseBody.put("message", "Role processed"); 17 return ResponseEntity.status(HttpStatus.CREATED).body(responseBody); 18 } catch (IOException e) { 19 return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); 20 } 21 } ``` * Go Create a webhook endpoint for role updates ```go 1 mux.HandleFunc("POST /webhook", func(w http.ResponseWriter, r *http.Request) { 2 // Read request body from the webhook payload 3 bodyBytes, err := io.ReadAll(r.Body) 4 if err != nil { 5 http.Error(w, err.Error(), http.StatusBadRequest) 6 return 7 } 8 9 // Parse webhook payload 10 var body struct { 11 Data map[string]interface{} `json:"data"` 12 } 13 14 if err := json.Unmarshal(bodyBytes, &body); err != nil { 15 http.Error(w, err.Error(), http.StatusBadRequest) 16 return 17 } 18 19 // Extract user data 20 roles, _ := body.Data["roles"] 21 email, _ := body.Data["email"] 22 23 fmt.Println("Roles:", roles) 24 fmt.Println("Email:", email) 25 26 w.WriteHeader(http.StatusCreated) 27 _, _ = w.Write([]byte(`{"message":"Role processed"}`)) 28 }) ``` Refer to the list of [directory webhook events](/directory/reference/directory-events/) you can subscribe to for more event types. --- # DOCUMENT BOUNDARY --- # Production readiness checklist > A focused checklist for launching your Scalekit SCIM provisioning integration, based on core enterprise authentication launch checks. As you prepare to launch SCIM provisioning to production, you should confirm that your configuration satisfies the SCIM-specific items from the authentication launch checklist. This page extracts the SCIM provisioning items from the main authentication [production readiness checklist](/authenticate/launch-checklist/) and organizes them for your directory rollout. **Verify production environment configuration** Confirm that your environment URL (`SCALEKIT_ENVIRONMENT_URL`), client ID (`SCALEKIT_CLIENT_ID`), and client secret (`SCALEKIT_CLIENT_SECRET`) are correctly configured for your production environment and match your production Scalekit dashboard settings. **Configure SCIM webhook endpoints** Configure webhook endpoints to receive SCIM events in your production environment, and ensure they use HTTPS and correct domain configuration. **Verify webhook security with signature validation** Implement signature validation for incoming SCIM webhooks so only Scalekit can trigger provisioning changes. See [webhook best practices](/guides/webhooks-best-practices/) for guidance. **Test user provisioning, updates, and deprovisioning** Test user provisioning flows (create), deprovisioning flows (deactivate or delete), and user profile updates to ensure your application responds correctly to each event type. **Validate group-based role assignment** Set up group-based role assignment and synchronization, and verify that group membership changes in the identity provider correctly map to roles and permissions in your application. **Handle duplicate and invalid data scenarios** Test error scenarios such as duplicate users, conflicting identifiers, and invalid data payloads so your integration fails safely and surfaces actionable errors. **Align SCIM with user and organization models** Confirm that your SCIM implementation matches your user and organization data model, including how you represent organizations, teams, and role assignments in your system. **Finalize admin portal configuration for directory admins** Ensure directory admins can configure SCIM connections in the admin portal, and that your branding and access controls are correct for enterprise customers. --- # DOCUMENT BOUNDARY --- # Onboard enterprise customers > Complete workflow for enabling SCIM provisioning and self-serve directory sync configuration for your enterprise customers Enterprise provisioning with SCIM enables you to automatically create, update, and deactivate users in your application based on changes in your customers’ directory providers such as Okta, Microsoft Entra ID, or Google Workspace. This gives enterprise customers centralized user lifecycle management while reducing manual administration and access drift. ![How Scalekit connects your application to enterprise directories and identity providers](/.netlify/images?url=_astro%2Fhow-scalekit-connects.CrZX8E30.png\&w=5776\&h=1924\&dpl=6aaa70ad2ea7b40008ad2afd) This guide walks you through the complete workflow for onboarding enterprise customers with SCIM provisioning. You’ll learn how to create organizations, provide admin portal access, enable directory sync, and verify that provisioning works end to end. Before onboarding enterprise customers with provisioning, ensure you have completed the [SCIM quickstart](/directory/scim/quickstart/) to set up basic directory sync in your application. ## Table of contents * [Create organization](#create-organization) * [Provide admin portal access](#provide-admin-portal-access) * [Customer configures SCIM provisioning](#customer-configures-scim-provisioning) * [Verify provisioning and run test sync](#verify-provisioning-and-run-test-sync) 1. ## Create organization Create an organization in Scalekit to represent your enterprise customer: * Log in to the [Scalekit dashboard](https://app.scalekit.com) * Navigate to **Dashboard > Organizations** * Click **Create Organization** * Enter the organization name and relevant details * Save the organization Each organization in Scalekit represents one of your enterprise customers and can have its own directory sync settings, SSO configuration, and domain associations. 2. ## Provide admin portal access Give your customer’s IT administrator access to the self-serve admin portal to configure their directory and SCIM connection. Scalekit provides two integration methods: **Option 1: Share a no-code link** Quick setup Generate and share a link to the admin portal: * Select the organization from **Dashboard > Organizations** * Click **Generate link** in the organization overview * Share the link with your customer’s IT admin via email, Slack, or your preferred channel The link remains valid for 7 days and can be revoked anytime from the dashboard. **Link properties:** | Property | Details | | -------------- | ------------------------------------------------------------------------------- | | **Expiration** | Links expire after 7 days | | **Revocation** | Revoke links anytime from the dashboard | | **Sharing** | Share via email, Slack, or any preferred channel | | **Security** | Anyone with the link can view and update the organization’s connection settings | The generated link follows this format: Portal link example ```http https://your-app.scalekit.dev/magicLink/2cbe56de-eec4-41d2-abed-90a5b82286c4_p ``` Security consideration Treat portal links as sensitive credentials. Anyone with the link can view and modify the organization’s SSO and SCIM configuration. **Option 2: Embed the portal** Seamless experience Embed the admin portal directly in your application so customers can configure SCIM provisioning and SSO without leaving your interface. The portal link must be generated programmatically on each page load for security. Each generated link is single-use and expires after 1 minute, though once loaded, the session remains active for up to 6 hours. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` ### Generate portal link Use the Scalekit SDK to generate a unique, embeddable admin portal link for an organization. Call this API endpoint each time you render the page containing the iframe: * Node.js Express.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new Scalekit( 4 process.env.SCALEKIT_ENVIRONMENT_URL, 5 process.env.SCALEKIT_CLIENT_ID, 6 process.env.SCALEKIT_CLIENT_SECRET, 7 ); 8 9 async function generatePortalLink(organizationId) { 10 const link = await scalekit.organization.generatePortalLink(organizationId); 11 return link.location; // Use as iframe src 12 } ``` * Python Flask ```python 1 from scalekit import Scalekit 2 import os 3 4 scalekit_client = Scalekit( 5 environment_url=os.environ.get("SCALEKIT_ENVIRONMENT_URL"), 6 client_id=os.environ.get("SCALEKIT_CLIENT_ID"), 7 client_secret=os.environ.get("SCALEKIT_CLIENT_SECRET") 8 ) 9 10 def generate_portal_link(organization_id): 11 link = scalekit_client.organization.generate_portal_link(organization_id) 12 return link.location # Use as iframe src ``` * Go Gin ```go 1 import ( 2 "context" 3 "os" 4 5 "github.com/scalekit/sdk-go" 6 ) 7 8 scalekitClient := scalekit.New( 9 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 10 os.Getenv("SCALEKIT_CLIENT_ID"), 11 os.Getenv("SCALEKIT_CLIENT_SECRET"), 12 ) 13 14 func generatePortalLink(organizationID string) (string, error) { 15 ctx := context.Background() 16 link, err := scalekitClient.Organization().GeneratePortalLink(ctx, organizationID) 17 if err != nil { 18 return "", err 19 } 20 return link.Location, nil // Use as iframe src 21 } ``` * Java Spring Boot ```java 1 import com.scalekit.client.Scalekit; 2 import com.scalekit.client.models.Link; 3 import com.scalekit.client.models.Feature; 4 import java.util.Arrays; 5 6 Scalekit scalekitClient = new Scalekit( 7 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 8 System.getenv("SCALEKIT_CLIENT_ID"), 9 System.getenv("SCALEKIT_CLIENT_SECRET") 10 ); 11 12 public String generatePortalLink(String organizationId) { 13 Link portalLink = scalekitClient.organizations() 14 .generatePortalLink(organizationId, Arrays.asList(Feature.sso, Feature.dir_sync)); 15 return portalLink.getLocation(); // Use as iframe src 16 } ``` The API returns a JSON object with the portal link. Use the `location` property as the iframe `src`: API response ```json { "id": "8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "location": "https://random-subdomain.scalekit.dev/magicLink/8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "expireTime": "2024-10-03T13:35:50.563013Z" } ``` Embed portal in iframe ```html ``` Embed the portal in your application’s settings or admin section where customers manage authentication configuration. Listen for UI events from the embedded portal to respond to configuration changes, such as when directory sync is enabled, provisioning is tested, or the session expires. See the [Admin portal UI events reference](/reference/admin-portal/ui-events/) for details on handling these events. ### Configuration and session | Setting | Requirement | | --------------------- | ----------------------------------------------------------------------------- | | **Redirect URI** | Add your application domain at **Dashboard > Developers > API Configuration** | | **iframe attributes** | Include `allow="clipboard-write"` for copy-paste functionality | | **Dimensions** | Minimum recommended height: 600px | | **Link expiration** | Generated links expire after 1 minute if not loaded | | **Session duration** | Portal session remains active for up to 6 hours once loaded | | **Single-use** | Each generated link can only be used once to initialize a session | 3. ## Customer configures SCIM provisioning After receiving admin portal access, your customer’s IT administrator: * Opens the admin portal (via shared link or embedded iframe) * Selects their directory integration (Okta, Microsoft Entra ID, Google Workspace, etc.) * Follows the provider-specific SCIM or directory sync setup guide * Enters the required configuration (SCIM endpoint URL, access token, and any required headers) * Tests user provisioning from their directory to your application * Activates the SCIM connection Once configured, the directory sync or SCIM connection appears as active in your organization’s settings. 4. ## Verify provisioning and run test sync After SCIM provisioning is configured, verify that user and group changes flow correctly from the customer’s directory into your application. This ensures your enterprise onboarding is reliable before rolling out broadly. To verify provisioning: * Create a test user in the customer’s directory and assign them to the appropriate groups or applications * Confirm that the user appears in your application’s organization with the expected attributes (name, email, roles, and status) * Update the user’s attributes or group memberships in the directory and verify that changes propagate to your application * Deactivate or delete the test user in the directory and ensure their access is revoked in your application ## Customize the admin portal Match the admin portal to your brand identity. Configure branding at **Dashboard > Settings > Branding**: | Option | Description | | ---------------- | --------------------------------------------------------- | | **Logo** | Upload your company logo (displayed in the portal header) | | **Accent color** | Set the primary color to match your brand palette | | **Favicon** | Provide a custom favicon for browser tabs | For additional customization options including custom domains, see the [Custom domain guide](/guides/custom-domain/). --- # DOCUMENT BOUNDARY --- # Review SCIM protocol > Learn about core components, resources, schemas, and real-world implementation scenarios for identity management across cloud applications through SCIM System for Cross-domain Identity Management (SCIM) is an [open standard API specification](https://datatracker.ietf.org/doc/html/rfc7643#section-2) designed to manage identities across cloud applications easily and scalably. The specification suite builds upon experience with existing schemas and deployments, emphasizing: * Simplicity of development and integration * Application of existing authentication, authorization, and privacy models Its intent is to reduce the cost and complexity of user management operations by providing: * A common user schema * An extension model; e.g., enterprise user * Binding documents to provide patterns for exchanging this schema using HTTP ## SCIM protocol: Key components [Section titled “SCIM protocol: Key components”](#scim-protocol-key-components) SCIM is a HTTP based protocol and uses structured [JSON](https://datatracker.ietf.org/doc/html/rfc7159) payloads to exchange resource information between the SCIM client and service provider. To identify the SCIM protocol resources, the `application/scim+json` media type is used. ### SCIM service provider [Section titled “SCIM service provider”](#scim-service-provider) SCIM service provider is any business application that provisions users and groups by synchronizing the changes made in a SCIM client, including creates, updates, and deletes. The synchronization enables end users to have seamless access to the business application for which they’re assigned, with up-to-date profiles and permissions. Scalekit acts as the SCIM service provider on your behalf and integrates with your customer’s identity providers or directory providers (e.g. Okta, Azure AD, Google Workspace, etc.) to provision users and groups. ### SCIM client [Section titled “SCIM client”](#scim-client) SCIM client facilitates provisioning, or managing user lifecycle events, through SCIM endpoints exposed by the SCIM service provider. Identity providers and HRMS act as very popular SCIM clients as they are treated as the source of truth for user identity data. Some of the most common SCIM clients are [Okta](https://www.okta.com), [Microsoft Entra ID (aka Azure AD)](https://www.microsoft.com/en-in/security/business/identity-access/microsoft-entra-id). ### SCIM endpoints [Section titled “SCIM endpoints”](#scim-endpoints) SCIM endpoints are the entry points to the SCIM API. They are the endpoints that the SCIM client will call to provision users and groups. The following are the most popular SCIM endpoints that any SCIM service provider should support: * `/Users` * `/Groups` ### SCIM methods [Section titled “SCIM methods”](#scim-methods) As SCIM is built on top of REST, SCIM methods are the HTTP methods that are used to perform CRUD operations on the SCIM resources. The following are the most common SCIM methods: * GET * POST * PUT * PATCH * DELETE ### SCIM authentication [Section titled “SCIM authentication”](#scim-authentication) SCIM uses OAuth 2.0 bearer token authentication to authenticate requests to the SCIM API. The token is a string that is used to authenticate the SCIM API requests to the SCIM service provider. The token is passed in the HTTP Authorization header using the Bearer scheme. ## SCIM resources [Section titled “SCIM resources”](#scim-resources) SCIM resources are the core building blocks of the SCIM protocol. They represent entities such as users, groups, and organizational units. Each resource has a set of attributes that describe the entity. While SCIM user resource has the basic attributes of a user like email address, phone number, and name, it is extensible by defining new JSON schemas that a service provider can choose to implement. An enterprise user is an example of a SCIM user extension resource. Enterprise user resource has attributes such as employee number, department, and manager which are valuable for enterprise implementation of user management using SCIM v2. Example SCIM user representation ```json 1 { 2 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], 3 "userName": "bjensen", 4 "name": { 5 "givenName": "Barbara", 6 "familyName": "Jensen" 7 }, 8 "emails": [ 9 { 10 "value": "bjensen@example.com", 11 "type": "work", 12 "primary": true 13 } 14 ], 15 "entitlements": [ 16 { 17 "value": "Employee", 18 "type": "role" 19 } 20 ] 21 } ``` ### SCIM schema [Section titled “SCIM schema”](#scim-schema) SCIM schema is the core of the SCIM protocol. It is a JSON schema that defines the structure of the SCIM resources. The following are the most common SCIM schemas: * [Core SCIM user schema](https://datatracker.ietf.org/doc/html/rfc7643#section-4.1) * [Enterprise user schema](https://datatracker.ietf.org/doc/html/rfc7643#section-4.3) * [Group schema](https://datatracker.ietf.org/doc/html/rfc7643#section-4.2) ## Putting everything together [Section titled “Putting everything together”](#putting-everything-together) Now that you have a high level understanding of the SCIM protocol and different components involved, let’s put everything together to take a scenario of how SCIM protocol facilitates user provisioning from an identity provider to a SCIM service provider like Scalekit. ### Scenario: New employee onboarding [Section titled “Scenario: New employee onboarding”](#scenario-new-employee-onboarding) 1. ACME Inc. hires a new employee, John Doe. 2. ACME Inc. adds John Doe to their Okta directory. 3. Okta send a SCIM `POST /Users` request to a pre-registered SCIM service provider (your B2B application) with John Doe’s information as per the SCIM protocol. 4. You authenticate the request using the OAuth 2.0 bearer token authentication & validate the request payload. 5. You provision John Doe as a new user in your B2B application using the user payload. ### Scenario: Employee termination [Section titled “Scenario: Employee termination”](#scenario-employee-termination) 1. ACME Inc. terminates John Doe’s employment. 2. ACME Inc. removes John Doe from their Okta directory. 3. Okta send a SCIM `DELETE /Users/john.doe` request to a pre-registered SCIM service provider (your B2B application) as per the SCIM protocol. 4. You authenticate the request using the OAuth 2.0 bearer token authentication & validate the request payload. 5. You deactivate John Doe as an existing user in your B2B application using the user payload. ### Scenario: Employee transfer [Section titled “Scenario: Employee transfer”](#scenario-employee-transfer) 1. ACME Inc. transfers John Doe to a different department. 2. ACME Inc. updates John Doe’s information in their Okta directory. 3. Okta send a SCIM `PATCH /Users/john.doe` request to a pre-registered SCIM service provider (your B2B application) as per the SCIM protocol. 4. You authenticate the request using the OAuth 2.0 bearer token authentication & validate the request payload. 5. You update John Doe’s information in your B2B application using the user payload. SCIM create user request ```http 1 POST /Users HTTP/1.1 2 Host: yourapp.scalekit.com/directory/dir_12442/scim/v2 3 Accept: application/scim+json 4 Content-Type: application/scim+json 5 Authorization: Bearer YOUR_SCIM_API_TOKEN 6 7 { 8 "schemas":["urn:ietf:params:scim:schemas:core:2.0:User"], 9 "userName":"bjensen", 10 "externalId":"bjensen", 11 "name":{ 12 "formatted":"Ms. Barbara J Jensen III", 13 "familyName":"Jensen", 14 "givenName":"Barbara" 15 } 16 } ``` ## Scalekit’s SCIM implementation [Section titled “Scalekit’s SCIM implementation”](#scalekits-scim-implementation) Scalekit’s SCIM implementation is built upon the principles of simplicity, security, and scalability. It provides a normalized implementation of the SCIM protocol across different identity providers & directory providers. This allows you to focus on integrating with Scalekit’s API & leave the complexities of SCIM protocol implementation to us. While not all directory providers implement SCIM or support all SCIM features, Scalekit aims to abstract these complexities & provide a seamless experience for provisioning users and groups. ### Webhooks [Section titled “Webhooks”](#webhooks) Scalekit supports webhooks as a mechanism to send real-time updates to your application about user provisioning and deprovisioning events to your application as and when there are changes detected in your customer’s SCIM compliant directory providers. We also normalize the webhook payloads across different directory providers to ensure that you can focus on building your application without having to worry about the nuances of each directory provider’s SCIM implementations. --- # DOCUMENT BOUNDARY --- # Understanding SCIM Provisioning > The business case for implementing SCIM Scaling organizations utilize a growing array of applications to support their employees’ productivity. To efficiently and securely manage access to these applications, organization administrators employ Directory Providers. These providers automate crucial workflows, such as granting access to new employees or revoking access for departing staff. Directory providers, like Entra ID (formerly Azure Active Directory), serve as the authoritative source for user information and access rights. Organizations expect your application to accommodate their directory provider requirements. Consequently, you must design systems capable of interfacing with various directory providers used by their customers. Scalekit serves as an intermediary component in your B2B application architecture, providing a streamlined interface to access user information programmatically and in real-time. ![User onboarding flow across your app, Scalekit, and directory providers](/.netlify/images?url=_astro%2Fbasics.BBrrKGoZ.png\&w=4260\&h=2200\&dpl=6aaa70ad2ea7b40008ad2afd) This solution allows your application to: 1. Automatically determine user roles (e.g., admin, member) 2. Retrieve user access permissions 3. Tailor the user experience accordingly and securely By integrating Scalekit, you can meet enterprise requirements without diverting focus from your core product development. This approach significantly reduces the engineering effort and time typically required to implement compatibility with various directory providers. Explore the compelling reasons to implement SCIM Provisioning in your B2B SaaS app: Implementing SCIM allows you to offer a more attractive, enterprise-grade solution. ## Next steps [Section titled “Next steps”](#next-steps) Now that you understand the importance of directories and how implementing SCIM Provisioning can step up your app to enterprise-grade status, it’s time to put this knowledge into action. Here are some suggested next steps: 1. Dive into our [Quickstart](/directory/scim/quickstart/) guide to learn how to set up SCIM Provisioning for your app. This practical guide will walk you through the implementation process step-by-step. 2. Start small by simulating directory events. This hands-on approach allows you to test and familiarize yourself with the system without affecting live data. 3. Explore our sample apps to picture all the moving components in a typical app. --- # DOCUMENT BOUNDARY --- # Directory events > Explore webhook events related to directory operations in Scalekit, including user and group creation, updates, and deletions. This page documents the webhook events related to directory operations in Scalekit. ## Table of contents * [Directory connection events](#directory-connection-events) * [`organization.directory_enabled`](#organizationdirectory_enabled) * [`organization.directory_disabled`](#organizationdirectory_disabled) * [Directory User Events](#directory-user-events) * [`organization.directory.user_created`](#organizationdirectoryuser_created) * [`organization.directory.user_updated`](#organizationdirectoryuser_updated) * [`organization.directory.user_deleted`](#organizationdirectoryuser_deleted) * [Directory Group Events](#directory-group-events) * [`organization.directory.group_created`](#organizationdirectorygroup_created) * [`organization.directory.group_updated`](#organizationdirectorygroup_updated) * [`organization.directory.group_deleted`](#organizationdirectorygroup_deleted) *** ## Directory connection events ### `organization.directory_enabled` This webhook is triggered when a directory sync is enabled. The event type is `organization.directory_enabled` organization.directory\_enabled ```json 1 { 2 "environment_id": "env_27758032200925221", 3 "id": "evt_55136848686613000", 4 "object": "Directory", 5 "occurred_at": "2025-01-15T08:55:22.802860294Z", 6 "organization_id": "org_55135410258444802", 7 "spec_version": "1", 8 "type": "organization.directory_enabled", 9 "data": { 10 "directory_type": "SCIM", 11 "enabled": false, 12 "id": "dir_55135622825771522", 13 "organization_id": "org_55135410258444802", 14 "provider": "OKTA", 15 "updated_at": "2025-01-15T08:55:22.792993454Z" 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------- | ------------------------------------------------------------- | | `id` | string | Unique identifier for the directory connection | | `directory_type` | string | The type of directory synchronization | | `enabled` | boolean | Indicates if the directory sync is enabled | | `environment_id` | string | Identifier for the environment | | `last_sync_at` | null | Timestamp of the last synchronization, null if not yet synced | | `organization_id` | string | Identifier for the organization | | `provider` | string | The provider of the directory | | `updated_at` | string | Timestamp of when the configuration was last updated | | `occurred_at` | string | Timestamp of when the event occurred | ### `organization.directory_disabled` This webhook is triggered when a directory sync is disabled. The event type is `organization.directory_disabled` organization.directory\_disabled ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891640779079756", 4 "type": "organization.directory_disabled", 5 "occurred_at": "2025-01-06T18:45:21.057814Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "Directory", 9 "data": { 10 "directory_type": "SCIM", 11 "enabled": false, 12 "id": "dir_53879621145330183", 13 "organization_id": "org_53879494091473415", 14 "provider": "OKTA", 15 "updated_at": "2025-01-06T18:45:21.04978184Z" 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------- | -------------------------------------------------------------------------------- | | `directory_type` | string | Type of directory protocol used for synchronization | | `enabled` | boolean | Indicates whether the directory synchronization is currently enabled or disabled | | `id` | string | Unique identifier for the directory connection | | `last_sync_at` | string | Timestamp of the most recent directory synchronization | | `organization_id` | string | Unique identifier of the organization associated with this directory | | `provider` | string | Identity provider for the directory connection | | `status` | string | Current status of the directory synchronization process | | `updated_at` | string | Timestamp of the most recent update to the directory connection | | `occurred_at` | string | Timestamp of when the event occurred | ## Directory User Events ### `organization.directory.user_created` This webhook is triggered when a new directory user is created. The event type is `organization.directory.user_created` organization.directory.user\_created ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891546994442316", 4 "type": "organization.directory.user_created", 5 "occurred_at": "2025-01-06T18:44:25.153954Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "DirectoryUser", 9 "data": { 10 "active": true, 11 "cost_center": "QAUZJUHSTYCN", 12 "custom_attributes": { 13 "mobile_phone_number": "1-579-4072" 14 }, 15 "department": "HNXJPGISMIFN", 16 "division": "MJFUEYJOKICN", 17 "dp_id": "", 18 "email": "flavio@runolfsdottir.co.duk", 19 "employee_id": "AWNEDTILGaIZN", 20 "family_name": "Jaquelin", 21 "given_name": "Dayton", 22 "groups": [ 23 { 24 "id": "dirgroup_12312312312312", 25 "name": "Group Name" 26 } 27 ], 28 "id": "diruser_53891546960887884", 29 "language": "se", 30 "locale": "LLWLEWESPLDC", 31 "name": "QURGUZZDYMFU", 32 "nickname": "DTUODYKGFPPC", 33 "organization": "AUIITQVUQGVH", 34 "organization_id": "org_53879494091473415", 35 "phone_number": "1-579-4072", 36 "preferred_username": "kuntala1233a", 37 "profile": "YMIUQUHKGVAX", 38 "raw_attributes": {}, 39 "title": "FKQBHCWJXZSC", 40 "user_type": "RBQFJSQEFAEH", 41 "zoneinfo": "America/Araguaina", 42 "roles": [ 43 { 44 "role_name": "billing_admin" 45 } 46 ] 47 } 48 } ``` | Field | Type | Description | | -------------------- | ------- | ---------------------------------------------------------------------------------- | | `id` | string | Unique ID of the Directory User | | `organization_id` | string | Unique ID of the Organization to which this directory user belongs | | `dp_id` | string | Unique ID of the User in the Directory Provider (IdP) system | | `preferred_username` | string | Preferred username of the directory user | | `email` | string | Email of the directory user | | `active` | boolean | Indicates if the directory user is active | | `name` | string | Fully formatted name of the directory user | | `roles` | array | Array of roles assigned to the directory user | | `groups` | array | Array of groups to which the directory user belongs | | `given_name` | string | Given name of the directory user | | `family_name` | string | Family name of the directory user | | `nickname` | string | Nickname of the directory user | | `picture` | string | URL of the directory user’s profile picture | | `phone_number` | string | Phone number of the directory user | | `address` | object | Address of the directory user | | `custom_attributes` | object | Custom attributes of the directory user | | `raw_attributes` | object | Raw attributes of the directory user as received from the Directory Provider (IdP) | ### `organization.directory.user_updated` This webhook is triggered when a directory user is updated. The event type is `organization.directory.user_updated` organization.directory.user\_updated ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891546994442316", 4 "type": "organization.directory.user_updated", 5 "occurred_at": "2025-01-06T18:44:25.153954Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "DirectoryUser", 9 "data": { 10 "id": "diruser_12312312312312", 11 "organization_id": "org_53879494091473415", 12 "dp_id": "", 13 "preferred_username": "", 14 "email": "john.doe@example.com", 15 "active": true, 16 "name": "John Doe", 17 "roles": [ 18 { 19 "role_name": "billing_admin" 20 } 21 ], 22 "groups": [ 23 { 24 "id": "dirgroup_12312312312312", 25 "name": "Group Name" 26 } 27 ], 28 "given_name": "John", 29 "family_name": "Doe", 30 "nickname": "Jhonny boy", 31 "picture": "https://image.com/profile.jpg", 32 "phone_number": "1234567892", 33 "address": { 34 "postal_code": "64112", 35 "state": "Missouri", 36 "formatted": "123, Oxford Lane, Kansas City, Missouri, 64112" 37 }, 38 "custom_attributes": { 39 "attribute1": "value1", 40 "attribute2": "value2" 41 }, 42 "raw_attributes": {} 43 } 44 } ``` | Field | Type | Description | | -------------------- | ------- | ---------------------------------------------------------------------------------- | | `id` | string | Unique ID of the Directory User | | `organization_id` | string | Unique ID of the Organization to which this directory user belongs | | `dp_id` | string | Unique ID of the User in the Directory Provider (IdP) system | | `preferred_username` | string | Preferred username of the directory user | | `email` | string | Email of the directory user | | `active` | boolean | Indicates if the directory user is active | | `name` | string | Fully formatted name of the directory user | | `roles` | array | Array of roles assigned to the directory user | | `groups` | array | Array of groups to which the directory user belongs | | `given_name` | string | Given name of the directory user | | `family_name` | string | Family name of the directory user | | `nickname` | string | Nickname of the directory user | | `picture` | string | URL of the directory user’s profile picture | | `phone_number` | string | Phone number of the directory user | | `address` | object | Address of the directory user | | `custom_attributes` | object | Custom attributes of the directory user | | `raw_attributes` | object | Raw attributes of the directory user as received from the Directory Provider (IdP) | #### `organization.directory.user_deleted` This webhook is triggered when a directory user is deleted. The event type is `organization.directory.user_deleted` organization.directory.user\_deleted ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891546994442316", 4 "type": "organization.directory.user_deleted", 5 "occurred_at": "2025-01-06T18:44:25.153954Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "DirectoryUser", 9 "data": { 10 "id": "diruser_12312312312312", 11 "organization_id": "org_12312312312312", 12 "dp_id": "", 13 "email": "john.doe@example.com" 14 } 15 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------ | | `id` | string | Unique ID of the Directory User | | `organization_id` | string | Unique ID of the Organization to which this directory user belongs | | `dp_id` | string | Unique ID of the User in the Directory Provider (IdP) system | | `email` | string | Email of the directory user | ## Directory Group Events ### `organization.directory.group_created` This webhook is triggered when a new directory group is created. The event type is `organization.directory.group_created` organization.directory.group\_created ```json 1 { 2 "spec_version": "1", 3 "id": "evt_38862741515010639", 4 "environment_id": "env_32080745237316098", 5 "object": "DirectoryGroup", 6 "occurred_at": "2024-09-25T02:26:39.036398577Z", 7 "organization_id": "org_38609339635728478", 8 "type": "organization.directory.group_created", 9 "data": { 10 "directory_id": "dir_38610496391217780", 11 "display_name": "Avengers", 12 "external_id": null, 13 "id": "dirgroup_38862741498233423", 14 "organization_id": "org_38609339635728478", 15 "raw_attributes": {} 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------ | --------------------------------------------------------- | | `directory_id` | string | Unique identifier for the directory | | `display_name` | string | Display name of the directory group | | `external_id` | null | External identifier for the group, null if not specified | | `id` | string | Unique identifier for the directory group | | `organization_id` | string | Identifier for the organization associated with the group | | `raw_attributes` | object | Raw attributes of the directory provider | ### `organization.directory.group_updated` This webhook is triggered when a directory group is updated. The event type is `organization.directory.group_updated` organization.directory.group\_updated ```json 1 { 2 "spec_version": "1", 3 "id": "evt_38864948910162368", 4 "organization_id": "org_38609339635728478", 5 "type": "organization.directory.group_updated", 6 "environment_id": "env_32080745237316098", 7 "object": "DirectoryGroup", 8 "occurred_at": "2024-09-25T02:48:34.745030921Z", 9 "data": { 10 "directory_id": "dir_38610496391217780", 11 "display_name": "Avengers", 12 "external_id": "", 13 "id": "dirgroup_38862741498233423", 14 "organization_id": "org_38609339635728478", 15 "raw_attributes": {} 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------ | --------------------------------------------------------- | | `directory_id` | string | Unique identifier for the directory | | `display_name` | string | Display name of the directory group | | `external_id` | null | External identifier for the group, null if not specified | | `id` | string | Unique identifier for the directory group | | `organization_id` | string | Identifier for the organization associated with the group | | `raw_attributes` | object | Raw attributes of the directory group | ### `organization.directory.group_deleted` This webhook is triggered when a directory group is deleted. The event type is `organization.directory.group_deleted` organization.directory.group\_deleted ```json 1 { 2 "spec_version": "1", 3 "id": "evt_40650399597723966", 4 "environment_id": "env_12205603854221623", 5 "object": "DirectoryGroup", 6 "occurred_at": "2024-10-07T10:25:26.289331747Z", 7 "organization_id": "org_39802449573184223", 8 "type": "organization.directory.group_deleted", 9 "data": { 10 "directory_id": "dir_39802485862301855", 11 "display_name": "Admins", 12 "dp_id": "7c66a173-79c6-4270-ac78-8f35a8121e0a", 13 "id": "dirgroup_40072007005503806", 14 "organization_id": "org_39802449573184223", 15 "raw_attributes": {} 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------- | | `directory_id` | string | Unique identifier for the directory | | `display_name` | string | Display name of the directory group | | `dp_id` | string | Unique identifier for the group in the directory provider system | | `id` | string | Unique identifier for the directory group | | `organization_id` | string | Identifier for the organization associated with the group | | `raw_attributes` | object | Raw attributes of the directory group as received from the provider | --- # DOCUMENT BOUNDARY --- # Just-in-time provisioning > Automatically provision users when they sign in through SSO for the first time Just-in-time (JIT) provisioning automatically creates users and organization memberships when they sign in through SSO for the first time. This feature allows users to access your application without requiring manual invitations from IT administrators. For example, users don’t need to remember separate credentials or go through additional signup steps - they just sign in through their familiar SSO portal. Your app signs them up instantly. ## Introduction [Section titled “Introduction”](#introduction) JIT provisioning is particularly useful for enterprise customers who want to provide seamless access to your application for their employees while maintaining security and control through their identity provider. When a user signs in through SSO for the first time, Scalekit automatically: 1. **Detects the verified domain** - Scalekit checks if the user’s email domain matches a verified domain in the organization 2. **Creates the user account** - A new user profile is created using information from the identity provider 3. **Establishes membership** - The user is automatically added as a member of the organization 4. **Completes authentication** - The user is signed in and redirected to your application This process happens seamlessly in the background, providing immediate access without manual intervention. ## Enabling JIT provisioning [Section titled “Enabling JIT provisioning”](#enabling-jit-provisioning) JIT provisioning must be enabled for each organization that wants to use this feature. You can enable it through the Scalekit Dashboard or programmatically using the API. ### Enable via Dashboard Coming soon [Section titled “Enable via Dashboard ”](#enable-via-dashboard-) 1. Log in to your [Scalekit Dashboard](https://app.scalekit.com). 2. Navigate to **Organizations** and select the organization. 3. Go to **Settings** and find the **JIT Provisioning** section. 4. Toggle the setting to enable JIT provisioning for this organization. ### Enable via API [Section titled “Enable via API”](#enable-via-api) You can also enable JIT provisioning programmatically using the Scalekit API: * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Enable JIT provisioning ```javascript 1 // Coming soon - API to enable JIT provisioning ``` ## Domain verification requirement [Section titled “Domain verification requirement”](#domain-verification-requirement) JIT provisioning only works for users whose email domains have been verified by the organization. This ensures that only legitimate members of the organization can automatically gain access to your application. **Organization admins** can verify domains through the [admin portal](/guides/admin-portal/). Once verified, any user with an email address from that domain can use JIT provisioning when signing in through SSO. ## What’s next? [Section titled “What’s next?”](#whats-next) * Learn about [Allowed Email Domains](/authenticate/manage-users-orgs/email-domain-rules/) for non-SSO authentication methods * Explore [Enterprise SSO](/sso/guides/onboard-enterprise-customers/) setup and configuration * Set up [organization switching](/authenticate/manage-users-orgs/organization-switching/) for users who belong to multiple organizations --- # DOCUMENT BOUNDARY --- # Brand your login page > Learn how to customize the look and feel of your Scalekit-hosted login page to match your brand. A sign up or a login page is the first interaction your users have with your application. It’s important to create a consistent and branded experience for your users. In this guide, we’ll show you how to customize the Scalekit-hosted login page to match your brand. ## Access branding settings [Section titled “Access branding settings”](#access-branding-settings) Navigate to **Customization** > **Branding** in your Scalekit dashboard. ![Scalekit Branding page with a login page preview and controls for logo, favicon, button colors, border radius, and logo position](/.netlify/images?url=_astro%2Flogin.DBMXYWSJ.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) ## Available customization options [Section titled “Available customization options”](#available-customization-options) | Setting | Description | Options | | -------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------- | | **Logo** | Upload your company logo for the sign-in box | Any image file or URL | | **Favicon** | Set a custom favicon for the browser tab | Any image file or URL | | **Border Radius** | Adjust the roundness of the login box corners | Small, Medium, Large | | **Logo Position** | Choose where your logo appears | Inside or outside the login box | | **Logo Alignment** | Align your logo horizontally | Left, Center, Right | | **Header Text Alignment** | Align the main header text | Left, Center, Right | | **Social Login Placement** | Control positioning of social login buttons | Various placement options | | **Background Color** | Set the background color of the login page | Color picker selection | | **Background Style** | Style the page background using CSS shorthand properties | Supports image, position, size, repeat, origin, clip, and attachment | ## Background Style configuration [Section titled “Background Style configuration”](#background-style-configuration) The Background Style setting allows you to fully customize your login page background using CSS shorthand properties. This powerful feature gives you complete control over how your background appears. ### Understanding CSS background shorthand [Section titled “Understanding CSS background shorthand”](#understanding-css-background-shorthand) CSS background shorthand combines multiple background properties into a single declaration. Instead of setting each property separately, you can define them all at once. ```css background: [background-color] [background-image] [background-position] [background-size] [background-repeat] [background-origin] [background-clip] [background-attachment]; ``` [Learn more on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/background) | Use case | Background Style value | Description | | ------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------- | | Background image | `url('https://example.com/your-image.jpg') center center/cover no-repeat` | Sets a background image that covers the entire page | | Position and repeat | `url('https://example.com/pattern.png') top left repeat` | Creates a tiled pattern with specific positioning | | Gradient | `linear-gradient(135deg, #4568DC, #B06AB3)` | Creates a smooth gradient transition between colors | | Image with fallback | `#f5f5f5 url('https://example.com/image.jpg') center center/cover no-repeat` | Uses a background color that shows if the image fails to load | --- # DOCUMENT BOUNDARY --- # Create and manage organizations > Create and manage organizations in Scalekit, configure settings, and enable enterprise features. Organizations are the foundation of your B2B application, representing your customers and their teams. In Scalekit, organizations serve as multi-tenant containers that isolate user data, configure authentication methods, and manage enterprise features like Single Sign-On (SSO) and directory synchronization. This guide shows you how to create and manage organizations programmatically and through the Scalekit dashboard. ## Understanding organizations [Section titled “Understanding organizations”](#understanding-organizations) Users can belong to multiple organizations with the same identity. This is common in products like Notion, where users collaborate across multiple workspaces. ## Create an organization [Section titled “Create an organization”](#create-an-organization) Organizations can be created automatically during user sign-up or programmatically through the API. When users sign up for your application, Scalekit creates a new organization and adds the user to it automatically. For more control over the organization creation process, create organizations programmatically: * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` - Node.js Create organization ```javascript 1 const organization = await scalekit.organization.createOrganization('Acme Corporation', { 2 externalId: 'acme-corp-123', 3 }); 4 5 console.log('Organization created:', organization.id); ``` - Python Create organization ```python 1 from scalekit.v1.organizations.organizations_pb2 import CreateOrganization 2 3 organization = scalekit_client.organization.create_organization( 4 CreateOrganization( 5 display_name='Acme Corporation', 6 external_id='acme-corp-123', 7 metadata={ 8 'plan': 'enterprise', 9 'industry': 'technology' 10 } 11 ) 12 ) 13 14 print(f'Organization created: {organization.id}') ``` - Go Create organization ```go 1 organization, err := scalekitClient.Organization.CreateOrganization( 2 ctx, 3 "Acme Corporation", 4 scalekit.CreateOrganizationOptions{ 5 ExternalId: "acme-corp-123", 6 }, 7 ) 8 if err != nil { 9 log.Fatal(err) 10 } 11 12 fmt.Printf("Organization created: %s\n", organization.ID) ``` - Java Create organization ```java 1 import java.util.Map; 2 import java.util.HashMap; 3 4 Map metadata = new HashMap<>(); 5 metadata.put("plan", "enterprise"); 6 metadata.put("industry", "technology"); 7 8 CreateOrganization createOrg = CreateOrganization.newBuilder() 9 .setDisplayName("Acme Corporation") 10 .setExternalId("acme-corp-123") 11 .build(); 12 13 Organization organization = scalekitClient.organizations().create(createOrg); 14 System.out.println("Organization created: " + organization.getId()); ``` **External ID**: An optional field to associate the organization with an ID from your system. This is useful for linking Scalekit organizations with records in your own database. ## Update organization details [Section titled “Update organization details”](#update-organization-details) Organization administrators often need to make changes after the initial setup. Typical examples include: * Renaming the organization after a corporate re-brand. * Uploading or replacing the company logo shown on your dashboard or invoices. * Storing metadata your application needs at runtime, such as a billing plan identifier, Stripe customer ID, or internal account reference. - Node.js Update organization ```javascript 1 const updatedOrganization = await scalekit.organization.updateOrganization( 2 'org_12345', 3 { 4 displayName: 'Acme Corporation Ltd', 5 metadata: { 6 plan: 'enterprise', 7 paymentMethod: 'stripe', 8 customField: 'custom-value' 9 } 10 } 11 ); ``` - Python Update organization ```python 1 updated_organization = scalekit_client.organization.update_organization( 2 organization_id='org_12345', 3 organization= UpdateOrganization( 4 display_name='Acme Corporation Ltd', 5 metadata={ 6 'plan': 'enterprise', 7 'payment_method': 'stripe', 8 'custom_field': 'custom-value' 9 } 10 ) 11 ) ``` - Go Update organization ```go 1 metadata := map[string]interface{}{ 2 "plan": "enterprise", 3 "payment_method": "stripe", 4 "custom_field": "custom-value", 5 } 6 7 update := &scalekit.UpdateOrganization{ 8 DisplayName: "Acme Corporation Ltd", 9 Metadata: metadata, 10 } 11 12 updatedOrganization, err := scalekitClient.Organization.UpdateOrganization(ctx, "org_12345", update) ``` - Java Update organization ```java 1 Map metadata = new HashMap<>(); 2 metadata.put("plan", "enterprise"); 3 metadata.put("payment_method", "stripe"); 4 metadata.put("custom_field", "custom-value"); 5 6 UpdateOrganization updateOrganization = UpdateOrganization.newBuilder() 7 .setDisplayName("Acme Corporation Ltd") 8 .putAllMetadata(metadata) 9 .build(); 10 11 Organization updatedOrganization = scalekitClient.organizations() 12 .updateById("org_12345", updateOrganization); ``` **Metadata**: Store additional information about the organization, such as subscription plans, payment methods, or any custom data relevant to your application. ## Configure organization features [Section titled “Configure organization features”](#configure-organization-features) Enable enterprise features for your organizations to support authentication methods like SSO and user provisioning through SCIM. * Node.js Enable organization features ```javascript 1 const settings = { 2 features: [ 3 { 4 name: 'sso', 5 enabled: true, 6 }, 7 { 8 name: 'dir_sync', 9 enabled: true, 10 }, 11 ], 12 }; 13 14 await scalekit.organization.updateOrganizationSettings( 15 'org_12345', 16 settings 17 ); ``` * Python Enable organization features ```python 1 settings = [ 2 {"sso": True}, 3 {"dir_sync": True}, 4 ] 5 6 scalekit_client.organization.update_organization_settings( 7 'org_12345', 8 settings 9 ) ``` * Go Enable organization features ```go 1 settings := scalekit.OrganizationSettings{ 2 Features: []scalekit.OrganizationSettingsFeature{ 3 {Name: "sso", Enabled: true}, 4 {Name: "dir_sync", Enabled: true}, 5 }, 6 } 7 8 _, err := scalekitClient.Organization.UpdateOrganizationSettings( 9 ctx, 10 "org_12345", 11 settings, 12 ) ``` * Java Enable organization features ```java 1 List settings = Arrays.asList( 2 OrganizationSettingsFeature.newBuilder() 3 .setName("sso") 4 .setEnabled(true) 5 .build(), 6 OrganizationSettingsFeature.newBuilder() 7 .setName("dir_sync") 8 .setEnabled(true) 9 .build() 10 ); 11 12 scalekitClient.organizations().updateOrganizationSettings( 13 "org_12345", 14 settings 15 ); ``` ### Limit user sign-ups in an organization [Section titled “Limit user sign-ups in an organization”](#limit-user-sign-ups-in-an-organization) Use this when you need seat caps per organization. For example, when organizations map to departments or when plans include per‑org seat limits. To set a limit from the dashboard: ![Scalekit User limit setting enabled and set to a maximum of 25 users per organization, with Save and Cancel buttons](/.netlify/images?url=_astro%2Flimit-org-users.F8VX5klf.png\&w=2454\&h=618\&dpl=6aaa70ad2ea7b40008ad2afd) 1. Go to Organizations → Select an Organization → User management 2. Find Organization limits and set max users per organization. Save changes. New users provisioning to this organizations are blocked until limits are increased. Configure them by updating the organization settings. ### Admin Portal access (self-serve configuration) [Section titled “Admin Portal access (self-serve configuration)”](#admin-portal-access-self-serve-configuration) Enterprise customers usually want to manage SSO and directory sync on their own, without involving your support team. Scalekit provides an **Admin Portal** that you can surface to IT administrators in two ways: 1. **Generate a shareable link** and send it via email or chat. 2. **Embed the portal** inside your own settings page with an ` ``` Embed the portal in your application’s settings or admin section where customers manage authentication configuration. ### Configuration and session [Section titled “Configuration and session”](#configuration-and-session) | Setting | Requirement | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Redirect URI** | Register the domain that hosts the iframe (your application’s own domain) as an **Allowed callback URL** at **Dashboard > Authentication > Redirects > Allowed Callback URLs** | | **iframe attributes** | Include `allow="clipboard-write"` for copy-paste functionality | | **Dimensions** | Minimum recommended height: 600px | | **Link expiration** | Generated links expire after 1 minute if not loaded | | **Session duration** | Portal session remains active for up to 6 hours once loaded | | **Single-use** | Each generated link can only be used once to initialize a session | Register the embedding domain The embedded portal loads only on domains you have registered. The domain of the page that hosts the iframe must be listed as an allowed callback URL (see the table above). If it is missing, the browser blocks the portal with a Content Security Policy (`frame-ancestors`) error and the iframe stays blank. ## Customize the admin portal [Section titled “Customize the admin portal”](#customize-the-admin-portal) Match the admin portal to your brand identity. Configure branding at **Dashboard > Settings > Branding**: | Option | Description | | ---------------- | --------------------------------------------------------- | | **Logo** | Upload your company logo (displayed in the portal header) | | **Accent color** | Set the primary color to match your brand palette | | **Favicon** | Provide a custom favicon for browser tabs | For additional customization options including custom domains, see the [Custom domain guide](/guides/custom-domain/). [SSO integrations](/guides/integrations/sso-integrations/)Administrator guides to set up SSO integrations [Portal events](/reference/admin-portal/ui-events/)Listen to the browser events emitted from the embedded admin portal --- # DOCUMENT BOUNDARY --- # Authenticate with Scalekit API > Learn how to authenticate your server applications with Scalekit API using OAuth 2.0 Client Credentials flow This guide explains how to authenticate your server applications with the Scalekit API using the OAuth 2.0 Client Credentials flow. After reading this guide, you’ll be able to: * Generate an access token using your API credentials * Make authenticated API requests to Scalekit endpoints * Handle authentication errors appropriately This guide targets developers who need to integrate Scalekit services into their backend applications or automate tasks through API calls. ## Before you begin [Section titled “Before you begin”](#before-you-begin) Before starting the authentication process, ensure you have set up your Scalekit account and obtained your API credentials. ## Step 1: Configure your environment [Section titled “Step 1: Configure your environment”](#step-1-configure-your-environment) Store your API credentials securely as environment variables: Environment variables ```sh 1 SCALEKIT_ENVIRONMENT_URL="" 2 SCALEKIT_CLIENT_ID="" 3 SCALEKIT_CLIENT_SECRET="" ``` ## Step 2: Request an access token [Section titled “Step 2: Request an access token”](#step-2-request-an-access-token) To authenticate your API requests, you must first obtain an access token from the Scalekit authorization server. ### Token endpoint URL [Section titled “Token endpoint URL”](#token-endpoint-url) Token endpoint URL ```sh 1 https:///oauth/token ``` ### Send a token request [Section titled “Send a token request”](#send-a-token-request) Choose your preferred method to request an access token: * cURL ```bash 1 curl -X POST \ 2 "https:///oauth/token" \ 3 -H "Content-Type: application/x-www-form-urlencoded" \ 4 -d "grant_type=client_credentials" \ 5 -d "client_id=" \ 6 -d "client_secret=" \ 7 -d "scope=openid profile email" ``` * Node.js ```javascript 1 import axios from 'axios'; 2 3 const config = { 4 clientId: process.env.SCALEKIT_CLIENT_ID, 5 clientSecret: process.env.SCALEKIT_CLIENT_SECRET, 6 tokenUrl: `${process.env.SCALEKIT_ENVIRONMENT_URL}/oauth/token`, 7 scope: 'openid email profile', 8 }; 9 10 async function getClientCredentialsToken() { 11 try { 12 const params = new URLSearchParams(); 13 params.append('grant_type', 'client_credentials'); 14 params.append('client_id', config.clientId); 15 params.append('client_secret', config.clientSecret); 16 17 if (config.scope) { 18 params.append('scope', config.scope); 19 } 20 21 const response = await axios.post(config.tokenUrl, params, { 22 headers: { 23 'Content-Type': 'application/x-www-form-urlencoded', 24 }, 25 }); 26 27 const { access_token, expires_in } = response.data; 28 console.log(`Token acquired successfully. Expires in ${expires_in} seconds.`); 29 return access_token; 30 } catch (error) { 31 console.error('Error getting client credentials token:', error); 32 throw new Error('Failed to obtain access token'); 33 } 34 } ``` * Python ```python 1 import os 2 import json 3 import requests 4 5 def get_access_token(): 6 """Request an access token using client credentials.""" 7 headers = {"Content-Type": "application/x-www-form-urlencoded"} 8 params = { 9 "grant_type": "client_credentials", 10 "client_id": os.environ['SCALEKIT_CLIENT_ID'], 11 "client_secret": os.environ['SCALEKIT_CLIENT_SECRET'] 12 } 13 oauth_token_url = os.environ['SCALEKIT_ENVIRONMENT_URL'] 14 15 response = requests.post(oauth_token_url, headers=headers, data=params, verify=True) 16 access_token = response.json().get('access_token') 17 return access_token ``` ### Understand the token response [Section titled “Understand the token response”](#understand-the-token-response) When your request succeeds, the server returns a JSON response with the following fields: | Field | Description | | -------------- | ----------------------------------------------------- | | `access_token` | The token you’ll use to authenticate API requests | | `token_type` | The token type (always Bearer for this flow) | | `expires_in` | Token validity period in seconds (typically 24 hours) | | `scope` | The authorized scopes for this token | Example token response: Token response ```json 1 { 2 "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InNua181Ok4OTEyMjU2NiIsInR5cCI6IkpXVCJ9...", 3 "token_type": "Bearer", 4 "expires_in": 86399, 5 "scope": "openid" 6 } ``` ## Step 3: Make authenticated API requests [Section titled “Step 3: Make authenticated API requests”](#step-3-make-authenticated-api-requests) After obtaining an access token, add it to the `Authorization` header in your API requests. * cURL ```bash 1 curl --request GET "https:///api/v1/organizations" \ 2 -H "Content-Type: application/json" \ 3 -H "Authorization: Bearer " ``` * Node.js (axios) ```javascript 1 async function makeAuthenticatedRequest(endpoint) { 2 try { 3 const access_token = await getClientCredentialsToken(); 4 const url = `${process.env.SCALEKIT_ENVIRONMENT_URL}${endpoint}`; 5 6 const response = await axios.get(url, { 7 headers: { 8 Authorization: `Bearer ${access_token}`, 9 }, 10 }); 11 12 console.log('API Response:', response.data); 13 return response.data; 14 } catch (error) { 15 console.error('Error making authenticated request:', error); 16 throw error; 17 } 18 } ``` * Python (requests) ```python 1 import os 2 import json 3 import requests 4 5 env_url = os.environ['SCALEKIT_ENVIRONMENT_URL'] 6 7 def get_access_token(): 8 """Request an access token using client credentials.""" 9 headers = {"Content-Type": "application/x-www-form-urlencoded"} 10 params = { 11 "grant_type": "client_credentials", 12 "client_id": os.environ['SCALEKIT_CLIENT_ID'], 13 "client_secret": os.environ['SCALEKIT_CLIENT_SECRET'] 14 } 15 16 response = requests.post( 17 url=f"{env_url}/oauth/token", 18 headers=headers, 19 data=params, 20 verify=True) 21 22 access_token = response.json().get('access_token') 23 return access_token 24 25 def get_organizations(get_orgs_endpoint): 26 """Retrieve all organizations for the specified environment.""" 27 access_token = get_access_token() 28 headers = {"Authorization": f"Bearer {access_token}"} 29 30 response = requests.get( 31 url=f"{env_url}/{get_orgs_endpoint}", 32 headers=headers) 33 return response ``` Example API response ```json 1 { 2 "next_page_token": "", 3 "total_size": 3, 4 "organizations": [ 5 { 6 "id": "org_64444217115541813", 7 "create_time": "2025-03-20T13:55:46.690Z", 8 "update_time": "2025-03-21T05:55:03.416772Z", 9 "display_name": "Looney Corp", 10 "region_code": "US", 11 "external_id": "my_unique_id", 12 "metadata": {} 13 } 14 ], 15 "prev_page_token": "" 16 } ``` ## Common authentication issues [Section titled “Common authentication issues”](#common-authentication-issues) | Issue | Possible cause | Solution | | ---------------- | ------------------------ | ------------------------------- | | 401 Unauthorized | Invalid or expired token | Generate a new access token | | 403 Forbidden | Insufficient permissions | Check client credentials scopes | | Connection error | Network or server issue | Retry with exponential backoff | ## Next steps [Section titled “Next steps”](#next-steps) Now that you can authenticate with the Scalekit API, you can: * Browse the complete API reference to discover available endpoints * Create a token management service to handle token refreshing * Implement error handling strategies for production use --- # DOCUMENT BOUNDARY --- # Best practices for client secrets > Learn best practices for managing Scalekit client secrets, including secure storage, rotation procedures, and access control to protect your SSO implementation. Client ID and Client Secret are a form of API credentials, like a username and password. You are responsible for keeping Client Secrets safe and secure. Below are some best practices for how you can keep your secrets safe and how you can leverage some of the functionality offered by us to help you do the same. **Store secrets securely** Whenever a client secret is generated from the Scalekit Dashboard, it is shown only once and cannot be recovered. Therefore, it should be immediately stored in a secure Key Management System (KMS), which offers encryption and access control features. It is crucial not to leave a duplicate copy of the key in the local file. **Avoid insecure sharing** Sharing of secret keys through insecure channels, such as emails, Slack, or customer support messages, should be strictly avoided. **Prevent hardcoding** Storing client secrets within source code as hardcoded strings should be avoided. Instead, store them in your properties file or environments file. These files should not be checked into your source code repository. **Establish rotation procedures** Establishing a Standard Operating Procedure (SOP) for rotating Client Secrets can help in case of accidental secret leakage. Having such procedures in place will ensure a swift and effective response to emergencies, minimizing business impact. **Control access** Access to create, update, or read keys should be granted only to those individuals who require it for their roles. Regularly auditing access can prevent excess privilege allocation. **Monitor usage** Regular monitoring of API logs is recommended to identify potential misuse of API keys early. Developers should avoid using live mode keys when a test mode key is suitable. **Respond to incidents** If suspicious activity is detected or a secret leak is suspected, the current secret should be immediately revoked from the Scalekit Dashboard, and a new one should be generated. In case of uncertainty, it is better to generate a new secret and revoke the existing one. --- # DOCUMENT BOUNDARY --- # Branded custom domains > Learn how to set up a branded custom domain with Scalekit Custom domain branding lets you provide a fully branded authentication experience for your customers. By default, Scalekit assigns a unique environment URL (like `https://yourapp.scalekit.com`), but you can replace it with your own domain (like `https://auth.yourapp.com`) using DNS CNAME configuration. This branded domain becomes the base URL for your admin portal, SSO connections, directory sync setup, and REST API endpoints—giving your customers a seamless, on-brand experience throughout their authentication journey. This guide shows you how to configure a CNAME record in your DNS registrar and verify SSL certificate provisioning for your custom domain. | Before | After | | ------------------------------ | -------------------------- | | `https://yourapp.scalekit.com` | `https://auth.yourapp.com` | Custom domains use DNS CNAME records to route traffic from your branded domain to Scalekit’s infrastructure: 1. Your custom domain (e.g., `auth.yourapp.com`) points to Scalekit’s infrastructure via a CNAME record 2. Scalekit automatically provisions and manages SSL certificates for your domain 3. All Scalekit services (Admin Portal, SSO endpoints, directory sync, REST API) become accessible through your branded domain This architecture ensures your domain remains on your brand while leveraging Scalekit’s secure, scalable infrastructure. CNAME records safely route traffic without exposing your configuration, and SSL certificates automatically provisioned by Scalekit ensure all traffic to your custom domain is encrypted (HTTPS). Existing integrations remain unaffected Integrations configured before the CNAME change will continue to work with your previous Scalekit domain. They don’t automatically update to use your custom domain. ### DNS record reference [Section titled “DNS record reference”](#dns-record-reference) When configuring your CNAME record, you’ll need to provide the following fields: | DNS Record Field | Example Value | Description | | ------------------------ | ----------------------- | ----------------------------------------------------------------------------------------- | | Record Type | `CNAME` | Canonical Name record that creates an alias from your domain to Scalekit’s infrastructure | | Name/Host/Label | `auth.yourapp.com` | Your custom subdomain (copied from Scalekit dashboard) | | Value/Target/Destination | `scalekit-prod-xyz.com` | Scalekit’s endpoint URL (copied from Scalekit dashboard) | | TTL | `3600` | Time to Live in seconds (optional, typically set by your registrar’s default) | ## Set up your custom domain [Section titled “Set up your custom domain”](#set-up-your-custom-domain) Let’s set up your custom domain by adding a CNAME record to your DNS registrar and verifying the configuration. 1. CNAME configuration is available only for production environments. Log into the Scalekit dashboard and ensure you’re working in your production environment. 2. In the Scalekit dashboard, go to **Dashboard > Customization > Custom Domain**. This page displays the CNAME record details you’ll need to configure in your DNS registrar. ![](/.netlify/images?url=_astro%2F1.BktW9U-H.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) 3. Go to your domain registrar’s DNS management console and create a new DNS record. Select `CNAME` as the record type. 4. In **Dashboard > Customization > Custom Domain**, copy the `Name` field (your desired subdomain). Paste this value into your DNS registrar’s `Name`, `Label`, or `Host` field. 5. Still in **Dashboard > Customization > Custom Domain**, copy the `Value` field. Paste this value into your DNS registrar’s `Destination`, `Target`, or `Value` field. 6. Save the CNAME record in your DNS registrar. The changes may take some time to propagate across DNS servers. 7. Return to **Dashboard > Customization > Custom Domain** in the Scalekit dashboard and click the **Verify** button. This validates that your CNAME record is properly configured and accessible. ### SSL certificate provisioning [Section titled “SSL certificate provisioning”](#ssl-certificate-provisioning) After successful CNAME verification, Scalekit automatically provisions an SSL certificate for your custom domain: * **Initial provisioning** - SSL certificate provisioning can take up to 24 hours after CNAME verification * **Check status** - Click the **Check** button in **Dashboard > Customization > Custom Domain** to verify SSL certificate status * **Still pending after 24 hours** - If SSL provisioning takes longer than 24 hours, contact our support team at [](mailto:support@scalekit.com) for assistance ## External resources [Section titled “External resources”](#external-resources) For detailed instructions on adding a CNAME record with popular DNS registrars: * [GoDaddy: Add a CNAME record](https://www.godaddy.com/en-in/help/add-a-cname-record-19236) * [Namecheap: How to create a CNAME record](https://www.namecheap.com/support/knowledgebase/article.aspx/9646/2237/how-to-create-a-cname-record-for-your-domain) --- # DOCUMENT BOUNDARY --- # How to register a callback endpoint > Learn how to register a callback endpoint in the Scalekit dashboard. In the authentication flow for a user, a callback endpoint is the endpoint that Scalekit remembers about your application, trusts it, and sends a authentication grant (code). It further expects your application to exchange the code for a user token and user profile. This needs to be pre-registered in the Scalekit dashboard. Go to **Dashboard** > **Authentication** > **Redirect URLS** > **Allowed Callback URLs** and add the callback endpoint. ![Scalekit Redirect URLs tab showing the Allowed callback URLs section with several registered callback endpoints and an Add URL button](/.netlify/images?url=_astro%2Fallowed-callback-url.BXvvAv1q.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) Your redirect URIs must meet specific requirements that vary between development and production environments: | Requirement | Development | Production | | ----------------- | ---------------------------- | -------------------- | | Supported schemes | `http` `https` `{scheme}` | `https` `{scheme}` | | Localhost support | Allowed | Not allowed | | Wildcard domains | Allowed | Not allowed | | URI length limit | 256 characters | 256 characters | | Query parameters | Not allowed | Not allowed | | URL fragments | Not allowed | Not allowed | Wildcards can simplify testing in development environments, but they must follow specific patterns: | Validation rule | Examples | | ------------------------------------------------ | -------------------------------------------------------------------- | | Wildcards cannot be used as root-level domains | `https://*.com``https://*.acmecorp.com``https://auth-*.acmecorp.com` | | Only one wildcard character is allowed per URI | `https://*.*.acmecorp.com``https://*.acmecorp.com` | | Wildcards must be in the hostname component only | `https://acmecorp.*.com``https://*.acmecorp.com` | | Wildcards must be in the outermost subdomain | `https://auth.*.acmecorp.com``https://*.auth.acmecorp.com` | Caution According to the [OAuth 2.0 specification](https://tools.ietf.org/html/rfc6749#section-3.1.2), redirect URIs must be absolute URIs. For development convenience, Scalekit relaxes this restriction slightly by allowing wildcards in development environments. --- # DOCUMENT BOUNDARY --- # View logs > Monitor authentication activities and webhook deliveries using comprehensive logs that track user sign-ins, authentication methods, and webhook event processing. Scalekit provides comprehensive logging for both authentication activities and webhook deliveries. Use these logs to monitor user access patterns, troubleshoot authentication issues, debug webhook integrations, and maintain compliance with audit requirements. ## Access logs [Section titled “Access logs”](#access-logs) **Authentication logs**: Navigate to **Dashboard > Auth Logs** to view all authentication events across your environment. ![](/.netlify/images?url=_astro%2F2.DFnmlRa6.png\&w=2936\&h=1956\&dpl=6aaa70ad2ea7b40008ad2afd) Each auth log entry displays the authentication event details, status, timestamp, user information, and authentication method used. **Webhook logs**: Navigate to **Dashboard > Webhooks** to view all configured webhook endpoints. Click on the specific webhook endpoint you want to monitor, then select the **”…”** (more options) button to access detailed delivery logs for that endpoint. ![](/.netlify/images?url=_astro%2Fdashboard.Ds15e5Zk.png\&w=2936\&h=1592\&dpl=6aaa70ad2ea7b40008ad2afd) Each webhook log entry displays the webhook event details, delivery status, timestamp, and response information from your application. ## Authentication statuses [Section titled “Authentication statuses”](#authentication-statuses) Auth logs display four different statuses that help you understand where users are in the authentication flow: | Status | Description | | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Initiated** | The user has started the authentication process by accessing the `/oauth/authorize` endpoint. This indicates they’ve begun the authorization flow but haven’t completed it yet. | | **Pending** | The authentication is in a transitional state between initiation and completion. During this phase, the system performs redirects while exchanging user profile details for authorization code grants. The authentication is still in progress. | | **Success** | The system successfully exchanged the authorization code grant, verified the user’s identity, and granted them access. The authentication flow has completed successfully. | | **Failure** | The authentication process failed and access was denied. This could be due to invalid credentials, network issues, interceptor rejections, or other authentication failures. Review the error details to identify the cause of the failure. | ## Filter auth logs [Section titled “Filter auth logs”](#filter-auth-logs) When investigating incidents or troubleshooting issues, use filters to narrow down log data and quickly identify authentication problems. **Available filters:** * **Time range** - Filter logs by specific date and time periods to focus on recent activity or investigate historical events * **User email** - Search for authentication events from specific users to track individual user activity or troubleshoot sign-in issues * **Authentication status** - Filter by Initiated, Pending, Success, or Failure to isolate specific authentication outcomes * **Organization** - View authentication events for specific organizations in multi-tenant applications Combine multiple filters to narrow your search. For example, filter by a specific user email and Failure status to investigate why a user cannot sign in. ## Webhook logs [Section titled “Webhook logs”](#webhook-logs) ### Webhook delivery statuses [Section titled “Webhook delivery statuses”](#webhook-delivery-statuses) Webhook logs display four different statuses that indicate the delivery state of each webhook event: | Status | Description | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Success** | Your application endpoint responded with a 2xx status code (typically 200 or 201), confirming successful receipt and processing of the webhook event. | | **Queued** | Due to high event volume or rate limiting, the webhook event is queued and waiting to be sent to your application endpoint. Events are processed in the order they were created. | | **Failed** | Your application endpoint did not respond, returned a non-2xx status code (typically 4xx or 5xx), or the request timed out. Failed deliveries trigger automatic retries. | | **Retrying** | Your application endpoint failed to acknowledge the webhook, and Scalekit is automatically retrying the delivery using exponential backoff. Retries continue up to 4 attempts with increasing delays between retries. | Monitor failed webhooks Failed webhooks can indicate issues with your endpoint availability, request validation, or processing logic. Review failed webhook logs to identify patterns and fix integration issues promptly. ### Filter webhook logs [Section titled “Filter webhook logs”](#filter-webhook-logs) When troubleshooting webhook delivery issues or investigating specific events, use filters to narrow down log data and quickly identify problems. **Available filters:** * **Time range** - Filter logs from the last 5 minutes to the last 30 days to focus on recent deliveries or investigate historical events * **Event type** - Filter by specific webhook event types (e.g., `organization.directory.user_created`, `organization.directory.user_updated`) to track particular types of events * **Delivery status** - Filter by Success, Queued, Failed, or Retrying to isolate problematic deliveries or verify successful processing Combine multiple filters to narrow your search. For example, filter by Failed status and a specific event type to investigate why certain events are not being processed successfully. ### Webhook log details [Section titled “Webhook log details”](#webhook-log-details) Click on any log entry to view detailed information about the webhook delivery: **Request details:** * Event ID and type * Timestamp when the event occurred * Request payload sent to your endpoint * Request headers including webhook signature **Response details:** * HTTP status code returned by your endpoint * Response body from your application * Response time and latency * Retry attempt number (if applicable) Use these details to debug webhook processing issues, verify signature validation, and ensure your endpoint handles events correctly. ### Retry behavior [Section titled “Retry behavior”](#retry-behavior) When webhook deliveries fail, Scalekit automatically retries sending the event to your endpoint: **Retry schedule:** * **Attempt 1**: Immediate delivery * **Attempt 2**: After 1 minute * **Attempt 3**: After 5 minutes * **Attempt 4**: After 15 minutes After the final retry attempt fails, the webhook is marked as permanently failed. You can view these failed webhooks in the logs and manually replay them when your endpoint is ready to process them. --- # DOCUMENT BOUNDARY --- # Custom email templates > Customize authentication email templates with your branding and content Scalekit uses default templates to send authentication emails to your users. You can customize these templates with your own branding and content to provide a consistent experience. Find these templates in **Emails** > **Templates**. ![Emails Custom Templates tab listing authentication email templates for login, sign-up, and organization invitations, each using the Scalekit type](/.netlify/images?url=_astro%2Fcustom-templates-list.C2tT6CvK.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) Select one of the listed templates and choose between Scalekit’s default templates or your own custom templates. ![Email template editor for a login verification email, with options to use the Scalekit or custom template, editable subject and HTML body, and a list of available variables](/.netlify/images?url=_astro%2Fsub-selection-custom-tempaltes.BCgqsBiR.png\&w=2856\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) Select how each email is generated: * **Use Scalekit template**: Preview subject and bodies; you cannot edit them. Emails use Scalekit’s default content. * **Use custom template**: Edit the subject, HTML body, and plain text body. Your saved content is used for future sends. Requires you to [bring your own email provider](/guides/passwordless/custom-email-provider/). ## Provide HTML and plain text versions [Section titled “Provide HTML and plain text versions”](#provide-html-and-plain-text-versions) Provide both versions of your email body in the template editor. When both are present, Scalekit sends a multipart/alternative message: HTML is shown in capable clients, and the plain text part is used as a fallback where HTML is not supported. Once saved, all subsequent emails will use your customized templates. ## Built-in template variables [Section titled “Built-in template variables”](#built-in-template-variables) Use these built-in variables in your templates. Values are injected at send time. The variables below apply to all Scalekit templates. #### Application [Section titled “Application”](#application) Use application variables to include app-level data (for example, name, logo, support email) that stays the same across all emails for your app. | Variable | Description | | -------------------------------- | ------------------------------------------------ | | `{{app_name}}` | Your application name | | `{{app_logo_url}}` | Public URL to your application logo | | `{{app_support_email}}` | Support email address for your application | | `{{app_organization_meta_name}}` | Organization display name configured in Scalekit | #### Organization [Section titled “Organization”](#organization) Organization variables describe the organization that the user belongs to and are consistent across emails for that organization. | Variable | Description | | ----------------------- | --------------------- | | `{{organization_name}}` | The organization name | #### User [Section titled “User”](#user) User variables personalize the email for the recipient (for example, name and email). | Variable | Description | | ---------------- | ----------------------------- | | `{{user_name}}` | The recipient’s name | | `{{user_email}}` | The recipient’s email address | #### Contextual [Section titled “Contextual”](#contextual) Contextual variables apply only to the current template. They change per template or send (for example, OTP, magic link, or expiry). For example, `{{link}}` is maybe the same label in both sign up and log in scenarios using magic link. | Variable | Description | | -------------------------- | ----------------------------------------------------------------------------- | | `{{link}}` | Authentication link (magic link or sign up) | | `{{otp}}` | One-time passcode for the current request | | `{{expiry_time_relative}}` | Human-readable relative date format (for example, “14 days, 6 hours, 50 min”) | ## JET template syntax [Section titled “JET template syntax”](#jet-template-syntax) Custom email templates use JET (Just Enough Templates) syntax for dynamic content. JET provides powerful templating features including conditionals, loops, and filters. Here are two common patterns you can use in your email templates: * Conditional welcome message ```html {{ if user_name }}

Hello {{ user_name }},

{{ else }}

Hello,

{{ end }}

Welcome to {{ app_name }}!

``` * User invite with organization ```html {{ if organization_name }}

You have been invited to join {{ organization_name }} organization in {{ app_name }}.

{{ else }}

You have been invited to {{ app_name }}.

{{ end }} ``` ## Inject you own variables at runtime Passwordless [Section titled “Inject you own variables at runtime ”](#inject-you-own-variables-at-runtime-) For more advanced personalization, you can use template variables to include values programatically in the emails. You must be using the Passwordless Headless API for authentication. * Each variable must be a key-value pair. * Maximum of 30 variables per template. * All template variables must have corresponding values in the request. * Avoid using reserved names: `otp`, `expiry_time_relative`, `link`, `expire_time`, `expiry_time`. 1. Create your email template with variables: Example email template ```html

Hello {{ first_name }},

Welcome to {{ company_name }}.

Find your onboarding kit: {{ onboarding_resources }}

``` 2. Include variable values in your authentication request: Authentication request ```js const sendResponse = await scalekit.passwordless.sendPasswordlessEmail( "", { templateVariables: { first_name: "John", company_name: "Acme Corp", onboarding_resources: "https://acme.com/onboarding" } } ); ``` 3. The sent email will include the replaced values: Example email preview ```html Hello John, Welcome to Acme Corp. Find your onboarding kit: https://acme.com/onboarding ``` Caution The API will return a 400 status code if your template references any variables that aren’t provided in the request. *** **Test your knowledge with a quiz** Which choice requires using your own email provider? * Use Scalekit template * Preview subject and bodies * Use custom template * Enable table of contents Submit --- # DOCUMENT BOUNDARY --- # Configure initiate login endpoint > Set up a login endpoint that Scalekit redirects to when users access your application through indirect entry points In certain scenarios, Scalekit redirects users to your application’s login endpoint using OIDC third-party initiated login. Your application must implement this endpoint to construct the authorization URL and redirect users to Scalekit’s authentication flow. Scalekit redirects to your login endpoint in these (example) scenarios: * **Bookmarked login page**: Users bookmark your login page and visit it later. When they access the bookmarked URL, Scalekit redirects them to your application’s login endpoint because the original authentication transaction has expired. * **Password reset completion**: After users complete a password reset, Scalekit redirects them to your login endpoint. Users can then sign in with their new password. * **Email verification completion**: After users verify their email address during signup, Scalekit redirects them to your login endpoint to complete authentication. * **Organization invitations**: When users click an invitation link to join an organization, Scalekit redirects them to your login endpoint with invitation parameters. Your application must forward these parameters to Scalekit’s authorization endpoint. * **Disabled cookies**: If users navigate to Scalekit’s authorization endpoint with cookies disabled, Scalekit redirects them to your login endpoint. ## Configure the initiate login endpoint [Section titled “Configure the initiate login endpoint”](#configure-the-initiate-login-endpoint) Register your login endpoint in the Scalekit dashboard. Go to **Dashboard** > **Authentication** > **Redirect URLs** > **Initiate Login URL** and add your endpoint. ![Scalekit Authentication settings showing the Initiate-login URL section with a registered endpoint and an Add URL button](/.netlify/images?url=_astro%2Fallowed-callback-url.BXvvAv1q.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) The endpoint must: * Use HTTPS (required in production) * Not point to localhost (production only) * Accept query parameters that Scalekit appends ## Implement the login endpoint [Section titled “Implement the login endpoint”](#implement-the-login-endpoint) Create a `/login` endpoint that constructs the authorization URL and redirects users to Scalekit. * Node.js routes/auth.js ```javascript 1 // Handle indirect auth entry points 2 app.get('/login', (req, res) => { 3 const redirectUri = 'http://localhost:3000/auth/callback'; 4 const options = { 5 scopes: ['openid', 'profile', 'email', 'offline_access'] 6 }; 7 8 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); 9 res.redirect(authorizationUrl); 10 }); ``` * Python routes/auth.py ```python 1 from flask import redirect 2 from scalekit import AuthorizationUrlOptions 3 4 # Handle indirect auth entry points 5 @app.route('/login') 6 def login(): 7 redirect_uri = 'http://localhost:3000/auth/callback' 8 options = AuthorizationUrlOptions() 9 options.scopes = ['openid', 'profile', 'email', 'offline_access'] 10 options.state = session['oauth_state'] 11 12 authorization_url = scalekit_client.get_authorization_url(redirect_uri, options) 13 return redirect(authorization_url) ``` * Go routes/auth.go ```go 1 // Handle indirect auth entry points 2 r.GET("/login", func(c *gin.Context) { 3 redirectUri := "http://localhost:3000/auth/callback" 4 options := scalekitClient.AuthorizationUrlOptions{ 5 Scopes: []string{"openid", "profile", "email", "offline_access"} 6 } 7 8 authorizationUrl, _ := scalekitClient.GetAuthorizationUrl(redirectUri, options) 9 c.Redirect(http.StatusFound, authorizationUrl.String()) 10 }) ``` * Java AuthController.java ```java 1 import org.springframework.web.bind.annotation.GetMapping; 2 import org.springframework.web.bind.annotation.RestController; 3 import java.net.URL; 4 5 // Handle indirect auth entry points 6 @GetMapping("/login") 7 public String login() { 8 String redirectUri = "http://localhost:3000/auth/callback"; 9 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 10 options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access")); 11 12 URL authorizationUrl = scalekitClient.authentication().getAuthorizationUrl(redirectUri, options); 13 return "redirect:" + authorizationUrl.toString(); 14 } ``` --- # DOCUMENT BOUNDARY --- # Organization-specific redirect URLs > Register one redirect URL pattern that Scalekit resolves to an organization-specific URL at runtime. Multi-tenant applications often need a different callback URL for each customer. Instead of registering a separate redirect URL for every organization, you can register a single template that Scalekit expands per organization at runtime. For example, `https://{{org_slug}}/oauth/callback` expands to `https://auth.megasoft.com/oauth/callback` for Megasoft and `https://auth.betacorp.com/oauth/callback` for Beta Corp, with no additional configuration needed. ## Available template variables [Section titled “Available template variables”](#available-template-variables) | Variable | Source | Example value | | ------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | `{{org_slug}}` | Organization’s slug field. Can be a single DNS label (`megasoft`) or a full hostname (`auth.megasoft.com`). | `auth.megasoft.com` | | `{{external_id}}` | Organization’s external ID from your system. | `megasoft-123` | | `{{custom_domain}}` | Any key stored in the organization’s metadata. | `metadata.custom_domain = "auth.megasoft.com"` | ## Register an organization-specific URL [Section titled “Register an organization-specific URL”](#register-an-organization-specific-url) Add organization-specific URLs in **Dashboard > Authentication > Redirects** and type the URL pattern directly into the input field. These URLs are valid in all three redirect fields: * **Allowed callback URLs**: where Scalekit sends users after authentication * **Post logout URL**: where Scalekit sends users after logout * **Initiate login URL**: where Scalekit sends IdP-initiated login requests ![Scalekit Redirect URLs settings showing allowed callback, initiate-login, and post-logout URLs using templated organization slug patterns](/.netlify/images?url=_astro%2F2026-05-22-12-22-55.CVFnVtd_.png\&w=2420\&h=1420\&dpl=6aaa70ad2ea7b40008ad2afd) Supported patterns for redirect URLs: | Pattern | Example | Notes | | ------------- | ------------------------------------------- | ------------------------------------------------------------- | | Subdomain | `https://{{org_slug}}.yourapp.com/callback` | `{{org_slug}}` is a single DNS label such as `acme` | | Full host | `https://{{org_slug}}/callback` | `{{org_slug}}` is a full hostname such as `auth.megasoft.com` | | Custom domain | `https://{{custom_domain}}/callback` | Value comes from org metadata | | Path variable | `https://yourapp.com/{{org_slug}}/callback` | Variable in the path component | DNS label constraint Template variables cannot span part of a DNS label. `https://app-{{org_slug}}.yourapp.com` is not valid; the placeholder must occupy the entire DNS label or the entire host. At runtime, Scalekit substitutes each `{{variable}}` with its resolved value, validates the expanded URL against registered templates, and redirects the user. For logout, the organization is resolved from the active session; if the session has expired, template expansion is skipped and the redirect is rejected. ## Set slug or metadata for an organization [Section titled “Set slug or metadata for an organization”](#set-slug-or-metadata-for-an-organization) Set `slug` on an organization to expand `{{org_slug}}` templates. Store any key in organization `metadata` to use it as a custom variable like `{{custom_domain}}`. Setting just one is enough. Use whichever fits your registered URL pattern. ### Via dashboard [Section titled “Via dashboard”](#via-dashboard) Navigate to **Organizations > Select an organization > Overview > Edit**. Add the organization slug in the **Slug** field. ![Create Organization dialog showing the Slug field](/.netlify/images?url=_astro%2F2026-05-22-12-46-21.vDYPy38g.png\&w=1842\&h=1386\&dpl=6aaa70ad2ea7b40008ad2afd) ### Via SDK [Section titled “Via SDK”](#via-sdk) * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` - Node.js Create organization with slug and metadata ```javascript 1 // Set slug, metadata, or both — each enables a different template variable. 2 const organization = await scalekit.organization.createOrganization( 3 'Megasoft', 4 { 5 slug: 'auth.megasoft.com', 6 metadata: { custom_domain: 'auth.megasoft.com' }, 7 } 8 ); ``` - Python Create organization with slug and metadata ```python 1 # Set slug, metadata, or both — each enables a different template variable. 2 from scalekit.v1.organizations.organizations_pb2 import CreateOrganization 3 4 organization = scalekit_client.organization.create_organization( 5 CreateOrganization( 6 display_name='Megasoft', 7 slug='auth.megasoft.com', 8 metadata={'custom_domain': 'auth.megasoft.com'}, 9 ) 10 ) ``` - Go Create organization with slug and metadata ```go 1 // Set slug, metadata, or both — each enables a different template variable. 2 slug := "auth.megasoft.com" 3 4 _, err := scalekitClient.Organization().CreateOrganization( 5 ctx, 6 "Megasoft", 7 scalekit.CreateOrganizationOptions{ 8 Slug: &slug, 9 Metadata: map[string]interface{}{ 10 "custom_domain": "auth.megasoft.com", 11 }, 12 }, 13 ) 14 if err != nil { 15 log.Fatal(err) 16 } ``` - Java Create organization with slug and metadata ```java 1 // Set slug, metadata, or both — each enables a different template variable. 2 // Requires scalekit-sdk-java v2.1.3+ 3 CreateOrganization create = CreateOrganization.newBuilder() 4 .setDisplayName("Megasoft") 5 .setSlug("auth.megasoft.com") 6 .putMetadata("custom_domain", "auth.megasoft.com") 7 .build(); 8 9 scalekitClient.organizations().create(create); ``` ## Pass organization\_id and redirect URL in the authorization request [Section titled “Pass organization\_id and redirect URL in the authorization request”](#pass-organization_id-and-redirect-url-in-the-authorization-request) Pass the organization-specific `redirect_uri` and `organization_id` in the authorization request. Scalekit validates the redirect URL against the registered pattern using the organization’s slug or metadata. See [set up login flow](/authenticate/fsa/implement-login/#set-up-login-flow) for the full auth call reference. * Node.js Authorization URL with organization\_id ```diff 1 +const redirectUri = 'https://auth.megasoft.com/oauth/callback'; 2 const options = { 3 scopes: ['openid', 'profile', 'email'], 4 state: sessionStorage.oauthState, 5 organizationId: 'org_12345', 6 }; 7 8 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); 9 res.redirect(authorizationUrl); ``` * Python Authorization URL with organization\_id ```diff 1 redirect_uri = 'https://auth.megasoft.com/oauth/callback' 2 options = AuthorizationUrlOptions() 3 options.scopes = ['openid', 'profile', 'email'] 4 options.state = session['oauth_state'] 5 options.organization_id = 'org_12345' 6 7 authorization_url = scalekit_client.get_authorization_url(redirect_uri, options) 8 return redirect(authorization_url) ``` * Go Authorization URL with organization\_id ```diff 1 +redirectUri := "https://auth.megasoft.com/oauth/callback" 2 options := scalekit.AuthorizationUrlOptions{ 3 Scopes: []string{"openid", "profile", "email"}, 4 State: state, 5 +OrganizationId: "org_12345", 6 } 7 8 authorizationUrl := scalekitClient.GetAuthorizationUrl(redirectUri, options) 9 http.Redirect(w, r, authorizationUrl, http.StatusFound) ``` * Java Authorization URL with organization\_id ```diff 1 +String redirectUri = "https://auth.megasoft.com/oauth/callback"; 2 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 3 options.setScopes(List.of("openid", "profile", "email")); 4 options.setState(state); 5 +options.setOrganizationId("org_12345"); 6 7 String authorizationUrl = scalekitClient.getAuthorizationUrl(redirectUri, options); 8 response.sendRedirect(authorizationUrl); ``` If no organization is in scope, the template is not expanded and the request is rejected. ## A worked example [Section titled “A worked example”](#a-worked-example) 1. **Register the URL pattern** In **Dashboard > Authentication > Redirects > Allowed callback URLs**, add the URL as `https://{{org_slug}}/oauth/callback`. 2. **Set the organization’s slug** For Megasoft, set `slug` to `auth.megasoft.com` (see [Set slug or metadata for an organization](#set-slug-or-metadata-for-an-organization) above). 3. **Pass the org-specific redirect URL and `organization_id` in the authorization request** When a Megasoft user signs in, Scalekit validates the `redirect_uri` against the registered pattern using the organization’s slug: ```plaintext 1 https:///oauth/authorize?client_id=...&redirect_uri=https://auth.megasoft.com/oauth/callback&organization_id=org_megasoft_123&... ``` 4. **Scalekit validates and redirects** Scalekit matches `https://auth.megasoft.com/oauth/callback` against the registered pattern `https://{{org_slug}}/oauth/callback` using Megasoft’s slug and redirects the user. --- # DOCUMENT BOUNDARY --- # Configure redirect URLs > Learn how to configure and validate redirect URLs in Scalekit for secure authentication flows, including callback, login, logout, and back-channel logout endpoints Redirects are registered endpoints in Scalekit that control where users are directed during authentication flows. You must configure these endpoints in the Scalekit dashboard before they can be used. All redirect URIs must be registered under Authentication settings in your Scalekit dashboard. This is a security requirement to prevent unauthorized redirects. ## Redirect endpoint types [Section titled “Redirect endpoint types”](#redirect-endpoint-types) ### Allowed callback URLs [Section titled “Allowed callback URLs”](#allowed-callback-urls) **Purpose**: Where users are sent after successful authentication to exchange authorization codes and retrieve profile information. **Example scenario**: A user completes sign-in and Scalekit redirects them to `https://yourapp.com/callback` where your application processes the authentication response. To add or remove an redirect URL, go to Dashboard > Authentication > Redirects > Allowed Callback URLs. ### Initiate login URL [Section titled “Initiate login URL”](#initiate-login-url) **Purpose**: When authentication does not initiate from your application, Scalekit redirects users back to your application’s login initiation endpoint. This endpoint should point to a route in your application that ultimately redirects users to Scalekit’s `/authorize` endpoint. **Example scenarios**: * **Bookmarked login page**: A user bookmarks your login page and visits it directly. Your application detects they’re not authenticated and redirects them to Scalekit’s authorization endpoint. * **Organization invitation flow**: A user clicks an invitation link to join an organization. Your application receives the invitation token and redirects the user to Scalekit’s authorization endpoint to complete the sign-up process. * **IdP-initiated SSO**: An administrator initiates single sign-on from their identity provider dashboard. The IdP redirects users to your application, which then redirects them to Scalekit’s authorization endpoint to complete authentication. * **Session expiration**: When a user’s session expires or they access a protected resource, they’re redirected to `https://yourapp.com/login` which then redirects to Scalekit’s authentication endpoint. ### Post logout URL [Section titled “Post logout URL”](#post-logout-url) **Purpose**: Where users are sent after successfully signing out of your application. **Example scenario**: After logging out, users are redirected to `https://yourapp.com/goodbye` to confirm their session has ended. ### Back channel logout URL [Section titled “Back channel logout URL”](#back-channel-logout-url) **Purpose**: A secure endpoint that receives notifications whenever a user is logged out from Scalekit, regardless of how the logout was initiated — admin triggered, user initiated, or due to session policies like idle timeout. **Example scenario**: When a user logs out from any application (user-initiated, admin-initiated, or due to session policies like idle timeout), Scalekit sends a logout notification to `https://yourapp.com/logout` to suggest termination of the user’s session across all connected applications, ensuring coordinated logout for enhanced security. ### Custom URI schemes [Section titled “Custom URI schemes”](#custom-uri-schemes) Custom URI schemes allow for redirects, enabling deep linking and native app integrations. Some applications include: * **Desktop applications**: Use schemes like `{scheme}://` for native app integration * **Mobile apps**: Use schemes like `myapp://` for mobile app deep linking **Example custom schemes**: * `{scheme}://auth/callback` - For custom scheme authentication * `myapp://login/callback` - For mobile app authentication ## URI validation requirements [Section titled “URI validation requirements”](#uri-validation-requirements) Your redirect URIs must meet specific requirements that vary between development and production environments: | Requirement | Development | Production | | ----------------- | ---------------------------- | -------------------- | | Supported schemes | `http` `https` `{scheme}` | `https` `{scheme}` | | Localhost support | Allowed | Not allowed | | Wildcard domains | Allowed | Not allowed | | URI length limit | 256 characters | 256 characters | | Query parameters | Not allowed | Not allowed | | URL fragments | Not allowed | Not allowed | ### Wildcard usage patterns [Section titled “Wildcard usage patterns”](#wildcard-usage-patterns) Wildcards can simplify testing in development environments, but they must follow specific patterns: | Validation rule | Examples | | ------------------------------------------------ | -------------------------------------------------------------------- | | Wildcards cannot be used as root-level domains | `https://*.com``https://*.acmecorp.com``https://auth-*.acmecorp.com` | | Only one wildcard character is allowed per URI | `https://*.*.acmecorp.com``https://*.acmecorp.com` | | Wildcards must be in the hostname component only | `https://acmecorp.*.com``https://*.acmecorp.com` | | Wildcards must be in the outermost subdomain | `https://auth.*.acmecorp.com``https://*.auth.acmecorp.com` | Caution According to the [OAuth 2.0 specification](https://tools.ietf.org/html/rfc6749#section-3.1.2), redirect URIs must be absolute URIs. For development convenience, Scalekit relaxes this restriction slightly by allowing wildcards in development environments. ## Different redirect URL per organization [Section titled “Different redirect URL per organization”](#different-redirect-url-per-organization) If you need a different callback URL for each customer organization — for example, `https://auth.megasoft.com/oauth/callback` for Megasoft and `https://auth.betacorp.com/oauth/callback` for Beta Corp — register a single URL pattern with variables instead of registering one URL per organization. See [Organization-specific redirect URLs](/guides/dashboard/org-redirect-urls/) for the full setup. --- # DOCUMENT BOUNDARY --- # Personalize email delivery > Learn how to personalize email delivery by using Scalekit's managed service or configuring your own SMTP provider for brand consistency and control. Email delivery is a critical part of your authentication flow. By default, Scalekit sends all authentication emails (sign-in verification, sign-up confirmation, password reset) through its own email service. However, for production applications, you may need more control over email branding, deliverability, and compliance requirements. Here are common scenarios where you’ll want to customize email delivery: * **Brand consistency**: Send emails from your company’s domain with your own sender name and email address to maintain brand trust * **Deliverability optimization**: Use your established email reputation and delivery infrastructure to improve inbox placement * **Compliance requirements**: Meet specific regulatory or organizational requirements for email handling and data sovereignty * **Email analytics**: Track email metrics and performance through your existing email service provider * **Custom domains**: Ensure emails come from your verified domain to avoid spam filters and build user trust * **Enterprise requirements**: Corporate customers may require emails to come from verified business domains Scalekit provides two approaches to handle email delivery, allowing you to choose the right balance between simplicity and control. ![Email delivery methods in Scalekit](/.netlify/images?url=_astro%2F1-email-delivery-method.DLKX49XJ.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) ## Use Scalekit’s managed email service Default [Section titled “Use Scalekit’s managed email service ”](#use-scalekits-managed-email-service-) The simplest approach requires no configuration. Scalekit handles all email delivery using its own infrastructure. **When to use this approach:** * Quick setup for development and testing * You don’t need custom branding * You want Scalekit to handle email deliverability **Default settings:** * **Sender Name**: Team workspace\_name * **From Email Address**: * **Infrastructure**: Fully managed by Scalekit No additional configuration is required. Your authentication emails will be sent automatically with these settings. ## Configure your own email provider [Section titled “Configure your own email provider”](#configure-your-own-email-provider) For production applications, you’ll likely want to use your own email provider to maintain brand consistency and control deliverability. When to use this approach: * You need emails sent from your domain * You want complete control over email deliverability * You need to meet compliance requirements (e.g. GDPR, CCPA) * You want to integrate with existing email analytics ### Gather your SMTP credentials [Section titled “Gather your SMTP credentials”](#gather-your-smtp-credentials) Before configuring, collect the following information from your email provider: | Field | Description | | -------------------- | ------------------------------------------ | | **SMTP Server Host** | Your provider’s SMTP hostname | | **SMTP Port** | Usually 587 (TLS) or 465 (SSL) | | **SMTP Username** | Your authentication username | | **SMTP Password** | Your authentication password | | **Sender Email** | The email address emails will be sent from | | **Sender Name** | The display name recipients will see | ### Configure SMTP settings in Scalekit [Section titled “Configure SMTP settings in Scalekit”](#configure-smtp-settings-in-scalekit) 1. Navigate to email settings In your Scalekit dashboard, go to **Emails**. 2. Select custom email provider Choose **Use your own email provider** from the email delivery options 3. Configure sender information ```plaintext 1 From Email Address: noreply@yourdomain.com 2 Sender Name: Your Company Name ``` 4. Enter SMTP configuration ```plaintext 1 SMTP Server Host: smtp.your-provider.com 2 SMTP Port: 587 3 SMTP Username: your-username 4 SMTP Password: your-password ``` 5. Save and test configuration Click **Save** to apply your settings, then send a test email to verify the configuration ### Common provider configurations [Section titled “Common provider configurations”](#common-provider-configurations) * SendGrid ```plaintext 1 Host: smtp.sendgrid.net 2 Port: 587 3 Username: apikey 4 Password: [Your SendGrid API Key] ``` * Amazon SES ```plaintext 1 Host: email-smtp.us-east-1.amazonaws.com 2 Port: 587 3 Username: [Your SMTP Username from AWS] 4 Password: [Your SMTP Password from AWS] ``` * Postmark ```plaintext 1 Host: smtp.postmarkapp.com 2 Port: 587 3 Username: [Your Postmark Server Token] 4 Password: [Your Postmark Server Token] ``` ## Test your email configuration [Section titled “Test your email configuration”](#test-your-email-configuration) After configuring your email provider, verify that everything works correctly: 1. Send a test email through your authentication flow 2. Check delivery to ensure emails reach the intended recipients 3. Verify sender information appears correctly in the recipient’s inbox 4. Confirm formatting, branding, links and buttons work as expected --- # DOCUMENT BOUNDARY --- # Managing organization identifiers & metadata > Learn how to use external IDs and metadata to manage and track organizations in Scalekit, associating your own identifiers and storing custom key-value pairs. Applications often need to manage and track resources in their own systems. Scalekit provides two features to help with this: * **External IDs**: Associate your own identifiers with organizations * **Metadata**: Store custom key-value pairs with organizations ### When to use external IDs and metadata [Section titled “When to use external IDs and metadata”](#when-to-use-external-ids-and-metadata) Use these features when you need to: * Track organizations using your own identifiers instead of Scalekit’s IDs * Store additional information about organizations like billing details or internal codes * Integrate Scalekit organizations with your existing systems ### Add an external ID to an organization [Section titled “Add an external ID to an organization”](#add-an-external-id-to-an-organization) External IDs let you identify organizations using your own identifiers. You can set an external ID when creating or updating an organization. #### Create a new organization with an external ID [Section titled “Create a new organization with an external ID”](#create-a-new-organization-with-an-external-id) This example shows how to create an organization with your custom identifier: Create a new organization with an external ID ```bash 1 curl https:///api/v1/organizations \ 2 --request POST \ 3 --header 'Content-Type: application/json' \ 4 --data '{ 5 "display_name": "Megasoft Inc", 6 "external_id": "CUST-12345-MGSFT", 7 }' ``` #### Update an existing organization’s external ID [Section titled “Update an existing organization’s external ID”](#update-an-existing-organizations-external-id) To change an organization’s external ID, use the update endpoint: Update an existing organization's external ID ```bash 1 curl 'https:///api/v1/organizations/{id}' \ 2 --request PATCH \ 3 --header 'Content-Type: application/json' \ 4 --data '{ 5 "display_name": "Megasoft Inc", 6 "external_id": "TENANT-12345-MGSFT", 7 }' ``` ### Add metadata to an organization [Section titled “Add metadata to an organization”](#add-metadata-to-an-organization) Metadata lets you store custom information as key-value pairs. You can add metadata when creating or updating an organization. #### Create a new organization with metadata [Section titled “Create a new organization with metadata”](#create-a-new-organization-with-metadata) This example shows how to store billing information with a new organization: Create a new organization with metadata ```bash 1 curl https:///api/v1/organizations \ 2 --request POST \ 3 --header 'Content-Type: application/json' \ 4 --data '{ 5 "display_name": "Megasoft Inc", 6 "metadata": { 7 "invoice_email": "invoices@megasoft.com" 8 } 9 }' ``` #### Update an existing organization’s metadata [Section titled “Update an existing organization’s metadata”](#update-an-existing-organizations-metadata) To modify an organization’s metadata, use the update endpoint: Update an existing organization's metadata ```bash 1 curl 'https:///api/v1/organizations/{id}' \ 2 --request PATCH \ 3 --header 'Content-Type: application/json' \ 4 --data '{ 5 "display_name": "Megasoft Inc", 6 "metadata": { 7 "invoice_email": "billing@megasoft.com" 8 } 9 }' ``` ### View external IDs and metadata [Section titled “View external IDs and metadata”](#view-external-ids-and-metadata) All organization endpoints that return organization details will include the external ID and metadata in their responses. This makes it easy to access your custom data when working with organizations. ### External ID constraints [Section titled “External ID constraints”](#external-id-constraints) External IDs have the following constraints: * **Unique per environment**: Each external ID must be unique across all organizations in the same Scalekit environment, regardless of region. * **Maximum length**: 255 characters. * **Searchable by `external_id`**: You can look up organizations by `external_id` using the `list organizations` endpoint. You cannot search organizations by a metadata field. #### Multi-region external ID pattern [Section titled “Multi-region external ID pattern”](#multi-region-external-id-pattern) If your application operates across multiple regions and your internal account IDs are unique only within a region, prefix each external ID with the region name to ensure uniqueness across your Scalekit environment: ```text 1 us-east-CUST-12345 # US East account 2 eu-west-CUST-12345 # EU West account with the same internal ID ``` This pattern keeps the region and account identifier in a single field and stays within the 255-character limit. ### Organization deletion and SCIM [Section titled “Organization deletion and SCIM”](#organization-deletion-and-scim) When you delete an organization in Scalekit, Scalekit automatically deletes all associated connections and SCIM configurations. No charges apply after deletion. However, if your customer’s identity provider has SCIM provisioning enabled, the IdP will continue attempting to send SCIM events after the organization is deleted. Because there is no active SCIM endpoint to receive those events, the IdP will log errors for each attempt. --- # DOCUMENT BOUNDARY --- # ID token claims > Inspect the contents of the ID token An ID token is a JSON Web Token (JWT) containing cryptographically signed claims about a user’s profile information. Scalekit issues this token after successful authentication. The ID token is a Base64-encoded JSON object with three parts: header, payload, and signature. Here’s an example of the payload. Note this is formatted for readability and the header and signature fields are skipped. Sample IdToken payload ```json 1 { 2 "iss": "https://yoursaas.scalekit.com", 3 "azp": "skc_12205605011849527", 4 "aud": ["skc_12205605011849527"], 5 "amr": ["conn_17576372041941092"], 6 "sub": "conn_17576372041941092;google-oauth2|104630259163176101050", 7 "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q", 8 "c_hash": "HK6E_P6Dh8Y93mRNtsDB1Q", 9 "iat": 1353601026, 10 "exp": 1353604926, 11 "name": "John Doe", 12 "given_name": "John", 13 "family_name": "Doe", 14 "picture": "https://lh3.googleusercontent.com/a/ACg8ocKNE4TZj2kyLOj094kie_gDlUyU7JCZtbaiEma17URCEf=s96-c", 15 "locale": "en", 16 "email": "john.doe@acmecorp.com", 17 "email_verified": true 18 } ``` ## Full list of ID token claims [Section titled “Full list of ID token claims”](#full-list-of-id-token-claims) | Claim | Presence | Description | | ---------------- | -------- | -------------------------------------------- | | `aud` | Always | Intended audience (client ID) | | `amr` | Always | Authentication method reference values | | `exp` | Always | Expiration time (Unix timestamp) | | `iat` | Always | Issuance time (Unix timestamp) | | `iss` | Always | Issuer identifier (Scalekit environment URL) | | `oid` | Always | Organization ID of the user | | `sub` | Always | Subject identifier for the user | | `at_hash` | Always | Access token hash | | `c_hash` | Always | Authorization code hash | | `azp` | Always | Authorized presenter (usually same as `aud`) | | `email` | Always | User’s email address | | `email_verified` | Optional | Email verification status | | `name` | Optional | User’s full name | | `family_name` | Optional | User’s surname or last name | | `given_name` | Optional | User’s given name or first name | | `locale` | Optional | User’s locale (BCP 47 language tag) | | `picture` | Optional | URL of user’s profile picture | ## Verifying the ID token [Section titled “Verifying the ID token”](#verifying-the-id-token) In some cases, you may need to parse the ID token manually—for example, to access custom claims that are not part of the standard `User` object in the SDK method. These details are encoded in the ID token as JSON Web Token (JWT). If you use the Scalekit SDK, token validation is handled automatically. For non-SDK integrations (e.g., Ruby, PHP, or other languages), follow the steps below. ### Key validation parameters [Section titled “Key validation parameters”](#key-validation-parameters) | Parameter | Value | | -------------------- | -------------------------------------------------------------------- | | Signing algorithm | `RS256` | | JWKS endpoint | `https:///keys` | | Issuer (`iss`) | Your Scalekit environment URL (e.g., `https://yourapp.scalekit.com`) | | OpenID configuration | `https:///.well-known/openid-configuration` | ### Manual validation steps [Section titled “Manual validation steps”](#manual-validation-steps) To verify the signature manually: 1. Fetch the OpenID configuration from `https:///.well-known/openid-configuration` to discover `issuer` and `jwks_uri`. 2. Fetch the public signing keys from the `jwks_uri` (e.g., `https:///keys`). 3. Use a JWT library for your language to decode and verify the token with `RS256` using those keys. 4. Validate the required claims listed below. ### Important claims [Section titled “Important claims”](#important-claims) When validating, pay attention to these claims: * **`iss` (Issuer)**: This must match your Scalekit environment URL. * **`aud` (Audience)**: This must match your application’s client ID. * **`exp` (Expiration Time)**: Ensure the token has not expired. * **`sub` (Subject)**: This uniquely identifies the user, often combining the `connection_id` and the identity provider’s unique user ID. * **`amr`**: Contains the `connection_id` used for authentication. This structure provides a neutral, factual reference for ID token claims in Scalekit, organized according to the data structure itself. An ID token is a cryptographically signed Base64-encoded JSON object containing name/value pairs about the user’s profile information. It is a JWT token. Validate an ID token before using it. Since you communicate directly with Scalekit over HTTPS and use your client secret to exchange the `code` for the ID token, you can be confident that the token comes from Scalekit and is valid. If you use the Scalekit SDK to exchange the code for the ID token, the SDK automatically decodes the base64url-encoded values, parses the JSON, validates the JWT, and accesses the claims within the ID token. --- # DOCUMENT BOUNDARY --- # Integrations > Explore Scalekit's comprehensive integration capabilities with SSO providers, social connections, SCIM provisioning, and authentication systems. Explore integration guides for SSO, social logins, SCIM provisioning, and connecting with popular authentication systems. ## Single sign-on integrations [Section titled “Single sign-on integrations”](#single-sign-on--integrations) Configure organization IdPs and connect it to Scalekit to implement enterprise-grade authentication for your users. ### Okta - SAML Configure SSO with Okta using SAML protocol [Know more →](/guides/integrations/sso-integrations/okta-saml) ### Microsoft Entra ID - SAML Set up SSO with Microsoft Entra ID (Azure AD) using SAML [Know more →](/guides/integrations/sso-integrations/azure-ad-saml) ![JumpCloud - SAML logo](/assets/logos/jumpcloud.png) ### JumpCloud - SAML Implement SSO with JumpCloud using SAML [Know more →](/guides/integrations/sso-integrations/jumpcloud-saml) ![OneLogin - SAML logo](/assets/logos/onelogin.svg) ### OneLogin - SAML Configure SSO with OneLogin using SAML [Know more →](/guides/integrations/sso-integrations/onelogin-saml) ### Google Workspace - SAML Set up SSO with Google Workspace using SAML [Know more →](/guides/integrations/sso-integrations/google-saml) ![Ping Identity - SAML logo](/assets/logos/pingidentity.png) ### Ping Identity - SAML Configure SSO with Ping Identity using SAML [Know more →](/guides/integrations/sso-integrations/pingidentity-saml) ### Microsoft AD FS - SAML Set up SSO with Microsoft Active Directory Federation Services using SAML [Know more →](/guides/integrations/sso-integrations/microsoft-ad-fs) ![Shibboleth - SAML logo](/assets/logos/shibboleth.png) ### Shibboleth - SAML Set up SSO with Shibboleth using SAML [Know more →](/guides/integrations/sso-integrations/shibboleth-saml) ### Generic SAML Configure SSO with any SAML-compliant identity provider [Know more →](/guides/integrations/sso-integrations/generic-saml) ### Okta - OIDC Configure SSO with Okta using OpenID Connect [Know more →](/guides/integrations/sso-integrations/okta-oidc) ### Microsoft Entra ID - OIDC Set up SSO with Microsoft Entra ID using OpenID Connect [Know more →](/guides/integrations/sso-integrations/microsoft-entraid-oidc) ### Google Workspace - OIDC Set up SSO with Google Workspace using OpenID Connect [Know more →](/guides/integrations/sso-integrations/google-oidc) ![JumpCloud - OIDC logo](/assets/logos/jumpcloud.png) ### JumpCloud - OIDC Set up SSO with JumpCloud using OpenID Connect [Know more →](/guides/integrations/sso-integrations/jumpcloud-oidc) ![OneLogin - OIDC logo](/assets/logos/onelogin.svg) ### OneLogin - OIDC Set up SSO with OneLogin using OpenID Connect [Know more →](/guides/integrations/sso-integrations/onelogin-oidc) ![Ping Identity - OIDC logo](/assets/logos/pingidentity.png) ### Ping Identity - OIDC Set up SSO with Ping Identity using OpenID Connect [Know more →](/guides/integrations/sso-integrations/pingidentity-oidc) ### Generic OIDC Configure SSO with any OpenID Connect provider [Know more →](/guides/integrations/sso-integrations/generic-oidc) ## Social connections [Section titled “Social connections”](#social-connections) Enable users to sign in with their existing accounts from popular platforms. Social connections reduce signup friction and provide a familiar authentication experience. ### Google Enable Google account authentication using OAuth 2.0 [Know more →](/guides/integrations/social-connections/google) ### GitHub Allow authentication using GitHub credentials [Know more →](/guides/integrations/social-connections/github) ### Microsoft Integrate Microsoft accounts for user authentication [Know more →](/guides/integrations/social-connections/microsoft) ### GitLab Enable GitLab-based authentication [Know more →](/guides/integrations/social-connections/gitlab) ### LinkedIn Allow users to sign in with LinkedIn accounts [Know more →](/guides/integrations/social-connections/linkedin) ### Salesforce Enable Salesforce-based authentication [Know more →](/guides/integrations/social-connections/salesforce) ## SCIM Provisioning integrations [Section titled “SCIM Provisioning integrations”](#scim-provisioning-integrations) SCIM (System for Cross-domain Identity Management) automates user provisioning between identity providers and applications. These guides help you set up SCIM integration with various identity providers. ### Microsoft Entra ID (Azure AD) Automate user provisioning with Microsoft Entra ID [Know more →](/guides/integrations/scim-integrations/azure-scim) ### Okta Automate user provisioning with Okta [Know more →](/guides/integrations/scim-integrations/okta-scim) ![OneLogin logo](/assets/logos/onelogin.svg) ### OneLogin Automate user provisioning with OneLogin [Know more →](/guides/integrations/scim-integrations/onelogin) ![JumpCloud logo](/assets/logos/jumpcloud.png) ### JumpCloud Automate user provisioning with JumpCloud [Know more →](/guides/integrations/scim-integrations/jumpcloud) ### Google Workspace Automate user provisioning with Google Workspace [Know more →](/guides/integrations/scim-integrations/google-dir-sync/) ![PingIdentity logo](/assets/logos/pingidentity.png) ### PingIdentity Automate user provisioning with PingIdentity [Know more →](/guides/integrations/scim-integrations/pingidentity-scim) ### Generic SCIM Configure SCIM provisioning with any SCIM-compliant identity provider [Know more →](/guides/integrations/scim-integrations/generic-scim) ## Authentication system integrations [Section titled “Authentication system integrations”](#authentication-system-integrations) Scalekit can coexist with your existing authentication systems, allowing you to add enterprise SSO capabilities without replacing your current setup. These integrations show you how to configure Scalekit alongside popular authentication platforms. ### Auth0 Integrate Scalekit with Auth0 for enterprise SSO [Know more →](/guides/integrations/auth-systems/auth0) ### Firebase Auth Add enterprise authentication to Firebase projects [Know more →](/guides/integrations/auth-systems/firebase) ### AWS Cognito Configure Scalekit with AWS Cognito user pools [Know more →](/guides/integrations/auth-systems/aws-cognito) --- # DOCUMENT BOUNDARY --- # Auth0 > Learn how to integrate Scalekit with Auth0 for seamless Single Sign-On (SSO) authentication, allowing enterprise users to log in via Scalekit. This guide is designed to provide you a walkthrough of integrating Scalekit with Auth0, thereby facilitating seamless Single Sign-on (SSO) authentication for your application’s users. We demonstrate how to configure Scalekit so that Auth0 can allow some of your enterprise users to login via Scalekit and still continue to act as the identity management solution for your users and manage the login, session management functionality. ![Scalekit - Auth0 Integration ](/.netlify/images?url=_astro%2F0.BR2e1VI4.png\&w=3270\&h=954\&dpl=6aaa70ad2ea7b40008ad2afd) Scalekit is designed as a fully compatible OpenID Connect (OIDC) provider, thus streamlining the integration. As Auth0 continues to act as your identity management system, you’ll be able to seamlessly integrate Single Sign-on into your application without having to write code. Ensure you have: * Access to Auth0’s Authenticate dashboard. You need to have a role as an ‘Admin’ or ‘Editor - Connections’ to create and edit OIDC connections on Auth0 * Access to your Scalekit dashboard ## Add Scalekit as OIDC connection [Section titled “Add Scalekit as OIDC connection”](#add-scalekit-as-oidc-connection) Use [Auth0 Connections API](https://auth0.com/docs/api/management/v2/connections/post-connections) to create Scalekit as a OpenID connection for your tenant. Sample curl command below: ```bash curl --request POST \ --url 'https://.us.auth0.com/api/v2/connections' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ --header 'authorization: Bearer ' \ --data-raw '{ "strategy": "oidc", "name": "Scalekit", "options": { "type": "back_channel", "discovery_url": "/.well-known/openid-configuration", "client_secret" : "", "client_id" : "", "scopes": "openid profile email" } }' ``` Caution Because of an [existing issue](https://community.auth0.com/t/creating-an-oidc-connection-fails-with-options-issuer-is-required-error/128189) in adding OIDC connections via Auth0 Management Console, you need to use Auth0 API to create OIDC connection. | Parameter | Description | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `AUTH0_TENANT_DOMAIN` | This is your Auth0 tenant url. Typically, looks like https\://yourapp.us.auth0.com | | `API_TOKEN` | [Generate an API token](https://auth0.com/docs/secure/tokens/access-tokens/management-api-access-tokens) from your Auth0 dashboard and use it to authenticate your Auth0 API calls | | `SCALEKIT_ENVIRONMENT_URL` | Find this in your [API config](https://app.scalekit.com) section of Scalekit Dashboard. For development use `https://{your-subdomain}.scalekit.dev`, for production use `https://{your-subdomain}.scalekit.com` | | `SCALEKIT_CLIENT_SECRET` | Generate a new client secret in your [API config](https://app.scalekit.com) section of Scalekit Dashboard and use that here | | `SCALEKIT_CLIENT_ID` | Find this in your [API config](https://app.scalekit.com) section of Scalekit Dashboard | After the successful execution of the above API call, you will see a new OpenID connection created in your Auth0 tenant. To confirm this, you can navigate to [Enterprise Connections](https://auth0.com/docs/authenticate/enterprise-connections#view-enterprise-connections) in your Auth0 dashboard. ## Register redirect URI in Scalekit [Section titled “Register redirect URI in Scalekit”](#register-redirect-uri-in-scalekit) After creating Scalekit as a new OIDC connection, you need to: 1. Copy the Callback URL from your Auth0 Dashboard 2. Add it as a new Allowed Callback URI in your Scalekit Authentication > Redirects section ## Copy callback URL from Auth0 [Section titled “Copy callback URL from Auth0”](#copy-callback-url-from-auth0) In your Auth0 dashboard, go to Authentication > Enterprise > OpenID Connect > Scalekit > Settings. Copy the “Callback URL” that’s available in the General section of settings. ![Copy Callback URL from your Auth0 Dashboard](/.netlify/images?url=_astro%2F1.BEM7Y6HL.png\&w=3154\&h=2154\&dpl=6aaa70ad2ea7b40008ad2afd) ## Set redirect URI in Scalekit API config [Section titled “Set redirect URI in Scalekit API config”](#set-redirect-uri-in-scalekit-api-config) Go to your Scalekit dashboard. Select environment as Development or Production. Navigate to **Authentication** > **Redirects** > **Allowed Callback URIs**. In the Allowed Callback URIs section, select **Add new URI**. Paste the Callback URL that you copied from Auth0 dashboard. Click on Add button. ![Add new Redirect URI in Scalekit Dashboard](/.netlify/images?url=_astro%2Fscreenshot.Dmtybz_t.png\&w=1422\&h=717\&dpl=6aaa70ad2ea7b40008ad2afd) ## Onboard Single Sign-on customers in Scalekit [Section titled “Onboard Single Sign-on customers in Scalekit”](#onboard-single-sign-on-customers-in-scalekit) To onboard new enterprise customers using Single Sign-on login, you need to: 1. Create an Organization in Scalekit 2. Generate Admin Portal link to allow your customers configure SSO settings 3. Configure Domain in the Scalekit dashboard for that Organization 4. Update Home Realm Discovery settings in your Auth0 tenant with this Organization’s domain ## Update home realm discovery in Auth0 [Section titled “Update home realm discovery in Auth0”](#update-home-realm-discovery-in-auth0) In step 2, you have successfully configured Scalekit as an OIDC connection in your Auth0 tenant. It’s time to enable Home Realm Discovery for your enterprise customers in Auth0. This configuration will help Auth0 determine which users to be routed to login via Single Sign-on. In your Auth0 dashboard, go to Authentication > Enterprise > OpenID Connect > Scalekit > Login Experience. Navigate to “Home Realm Discovery” in the Login Experience Customization section. In the Identity Provider domains, add the comma separated list of domains that need to be authenticated with Single Sign-on via Scalekit. Auth0 uses this configuration to compare the users email domain at the time of login: * If there is a match in the configured domains, users will be redirected to the Scalekit’s Single Sign-on * If there is no match, users will be prompted to login via other authentication methods like password or Magic Link & OTP based on your Auth0 configuration For example, if you would like users from three Organizations (FooCorp, BarCorp, AcmeCorp) to access your application using their respective identity providers, you need to add them as a comma separated list foocorp.com, barcorp.com, acmecorp.com. Screenshot below for reference ![Add domains for Home Realm Discovery in Auth0](/.netlify/images?url=_astro%2F3.BFtPgz8x.png\&w=2796\&h=1670\&dpl=6aaa70ad2ea7b40008ad2afd) **Save** the Home Realm Discovery settings. You have now successfully integrated Scalekit with Auth0, thereby facilitating seamless SSO authentication for your application’s users. --- # DOCUMENT BOUNDARY --- # AWS Cognito > Learn how to integrate Scalekit with AWS Cognito as an OIDC provider for seamless enterprise Single Sign-On (SSO) authentication. Expand your existing AWS Cognito authentication system by integrating Scalekit as an OpenID Connect (OIDC) provider. This integration enables enterprise users to log into your application seamlessly using Single Sign-On (SSO). ![Integration flow: your application connects to AWS Cognito over OpenID Connect, then to Scalekit, which links to customer identity providers via SAML and OpenID Connect](/.netlify/images?url=_astro%2F0.vqDHIV-X.png\&w=3270\&h=954\&dpl=6aaa70ad2ea7b40008ad2afd) Here’s a typical flow illustrating the integration: 1. **User initiates login**: Enterprise users enter their company email address on your application’s custom login page (not managed by AWS Cognito) to initiate SSO 2. **Authentication via Scalekit**: Based on identifiers such as the user’s company email and Scalekit’s connection identifier, users are redirected to authenticate through their organization’s Identity Provider (IdP) Prefer exploring an example app? Check out this [Next.js example on GitHub](https://github.com/scalekit-developers/nextjs-example-apps/tree/main/cognito-scalekit) ## Configure Scalekit as an OIDC provider in AWS Cognito [Section titled “Configure Scalekit as an OIDC provider in AWS Cognito”](#configure-scalekit-as-an-oidc-provider-in-aws-cognito) To enable AWS Cognito to redirect users to Scalekit for SSO initiation, configure your Scalekit account as an OIDC provider within AWS Cognito: 1. Navigate to **AWS Cognito** and select your existing **User Pool** 2. Under the **Authentication** section, choose **Social and external providers** 3. Click **Add identity provider > OpenID Connect (OIDC)** AWS Cognito will display a form requiring specific details to establish the connection with Scalekit: ![Scalekit - AWS Cognito Integration](/.netlify/images?url=_astro%2F1.sOx18KK4.png\&w=2048\&h=1072\&dpl=6aaa70ad2ea7b40008ad2afd) AWS Cognito - Add Identity Provider | **Field** | **Description** | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Provider Name | A recognizable label for Scalekit within the AWS ecosystem. This name is used programmatically when generating authorization URLs. For example: `ScalekitIdPRouter` | | Client ID | Obtain this from your Scalekit Dashboard under **Authentication** > **Redirects** > **Allowed Callback URIs** | | Client Secret | Generate a secret from your Scalekit Dashboard (**Authentication** > **Redirects** > **Allowed Callback URIs**) and input it here | | Authorized Scopes | Scopes defining the user attributes that AWS Cognito can access from Scalekit | | Identifiers | Identifiers instruct AWS Cognito to check user-entered email addresses during sign-in and direct users accordingly to the associated identity provider based on their domain | | Attribute Request Method | Method used to exchange attributes and generate tokens for users; ensure you map Scalekit’s user attributes correctly to your user pool attributes in AWS Cognito | | Issuer URL | Enter your Scalekit environment URL found in the Scalekit Dashboard under **Authentication** > **Redirects** > **Allowed Callback URIs**. For development use `https://{your-subdomain}.scalekit.dev` and for production use `https://{your-subdomain}.scalekit.com` | Scalekit’s profile information includes various user attributes useful for your application requirements. Map these attributes between both providers using the attribute list found at **Scalekit Dashboard > Authentication > Single Sign-On**. This ensures standardized information exchange between your customers’ identity providers and your application. ![Scalekit - AWS Cognito Integration](/.netlify/images?url=_astro%2F2.BFLDa-7t.png\&w=2048\&h=1120\&dpl=6aaa70ad2ea7b40008ad2afd) The same attribute names are considered OpenID Connect attributes within AWS Cognito, streamlining user profile synchronization between your app and identity providers. ![Scalekit - AWS Cognito Integration](/.netlify/images?url=_astro%2F3.C3utCsuA.png\&w=2048\&h=1119\&dpl=6aaa70ad2ea7b40008ad2afd) Click **Add identity provider** to complete adding Scalekit as an identity provider. ## Implement Single Sign-On in your application [Section titled “Implement Single Sign-On in your application”](#implement-single-sign-on-in-your-application) Your application should use its own custom login page instead of the managed login page provided by AWS Cognito. This approach allows you to collect enterprise users’ email addresses and redirect them appropriately for authentication via SSO. ![Scalekit - AWS Cognito Integration](/.netlify/images?url=_astro%2F4.ClJKzgig.png\&w=1356\&h=764\&dpl=6aaa70ad2ea7b40008ad2afd) Generate an authorization URL with two additional parameters, `identity_provider` and `login_hint`, to redirect users seamlessly: Example Code ```typescript 1 import { Issuer, Client } from "openid-client"; 2 3 const client = await getOidcClient(); 4 5 const authUrl = client.authorizationUrl({ 6 scope: "openid email", 7 state: state, 8 nonce: nonce, 9 identity_provider: "ScalekitIdPRouter", // Same as Provider name (above) 10 login_hint: email, // User's company email address 11 }); 12 console.log("authUrl", authUrl); 13 const response = NextResponse.redirect(authUrl); ``` ### Example authorization endpoint URL [Section titled “Example authorization endpoint URL”](#example-authorization-endpoint-url) Here’s an example of a complete authorization endpoint URL incorporating the required parameters: ```sh 1 https://[domain].auth.[region].amazoncognito.com/oauth2/authorize 2 ?client_id=k6tana1l8b0bvhk9gfixkurr6 3 &scope=openid%20email 4 &response_type=code 5 &redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback 6 &state=-5iLRZmPwwdqwqT-A4yiJM6KQvCLQM0JRx9QaXOlzRE 7 &nonce=sGSXePnJ0Ue5GZyTpKG4rRsVeWyfZloImbMWunUDbG4 8 &identity_provider=ScalekitIdPRouter 9 &login_hint=enterpriseuser%40example.org ``` For ease of development, Scalekit supports testing with `@example.org` and `@example.com` domains. Authorization endpoints generated using these domains as `login_hint` will redirect enterprise users to Scalekit’s built-in IdP Simulator. ![Scalekit - AWS Cognito Integration](/.netlify/images?url=_astro%2F5.CZPyx7vZ.png\&w=2048\&h=1306\&dpl=6aaa70ad2ea7b40008ad2afd) Treat the IdP Simulator as equivalent to an actual organization’s IdP authentication step. For instance, if John belongs to Megasoft (using Okta as their IdP), logging in with `john@megasoft.org` would redirect him to Okta’s authentication process (including MFA or other organizational policies). Scalekit integrates seamlessly with [major identity providers](/guides/integrations/sso-integrations/). Use Scalekit’s [Admin Portal](/guides/admin-portal/) to onboard enterprise customers, enabling them to set up connections between their identity providers and your application. ### Successful SSO response [Section titled “Successful SSO response”](#successful-sso-response) Upon successful authentication via SSO, your application receives user profile details mapped according to AWS Cognito’s configured user attributes: Successful SSO response ```json { "sub": "807c593c-d0c1-709c-598f-633ec61bcc8b", "email_verified": "false", "email": "john@example.com", "username": "scalekitIdPRouter_conn_60040666217971987;a2c49d97-d36f-460f-97c2-87eb295095af" } ``` Now that you’ve successfully integrated AWS Cognito with Scalekit for SSO, here are some recommended next steps. Onboard Enterprise Customers using the Scalekit Admin Portal to help customers configure their identity providers. --- # DOCUMENT BOUNDARY --- # Co-exist with Firebase > Learn how to integrate Scalekit with Firebase for enterprise SSO, using either Firebase's OIDC provider or direct SSO with custom tokens. This guide explains how to integrate Scalekit with Firebase applications for enterprise Single Sign-On (SSO) authentication. You’ll learn two distinct approaches based on your Firebase Authentication setup. ![Scalekit - Firebase Integration](/.netlify/images?url=_astro%2F0.yumx0AEz.png\&w=3270\&h=954\&dpl=6aaa70ad2ea7b40008ad2afd) ## Before you begin [Section titled “Before you begin”](#before-you-begin) Review your Firebase Authentication setup to determine which integration approach suits your application: * **Option 1**: Requires Firebase Authentication with Identity Platform (paid tier) * **Option 2**: Works with Legacy Firebase Authentication (free tier) You also need: * Access to a [Scalekit account](https://app.scalekit.com) * Firebase project with Authentication enabled * Basic understanding of [Firebase Admin SDK](https://firebase.google.com/docs/reference/admin) (for Option 2) Checkout our [Firebase integration example](https://github.com/scalekit-inc/scalekit-firebase-sso) for a complete implementation. ## Option 1: Configure Scalekit as an OIDC Provider [Section titled “Option 1: Configure Scalekit as an OIDC Provider”](#option-1-configure-scalekit-as-an-oidc-provider) Use this approach if you have **Firebase Authentication with Identity Platform**. Firebase acts as an OpenID Connect (OIDC) relying party that integrates directly with Scalekit. Firebase handles the OAuth 2.0 flow automatically using its built-in OIDC provider support. 1. #### Configure Firebase to accept Scalekit as an identity provider [Section titled “Configure Firebase to accept Scalekit as an identity provider”](#configure-firebase-to-accept-scalekit-as-an-identity-provider) Log in to the [Firebase Console](https://console.firebase.google.com/) and navigate to your project. * Go to **Authentication** > **Sign-in method** * Click **Add new provider** and select **OpenID Connect** * Set the **Name** to “Scalekit” * Choose **Code flow** for the **Grant Type** ![Sign-in tab in your Firebase Console](/.netlify/images?url=_astro%2F1.CzGhJ8GY.png\&w=2952\&h=2474\&dpl=6aaa70ad2ea7b40008ad2afd) 2. #### Copy your Scalekit API credentials [Section titled “Copy your Scalekit API credentials”](#copy-your-scalekit-api-credentials) In your Scalekit Dashboard, navigate to **Settings** > **API Config** and copy these values: * **Client ID**: Your Scalekit application identifier * **Environment URL**: Your Scalekit environment (e.g., `https://your-subdomain.scalekit.dev`) * **Client Secret**: Generate a new secret if needed ![Scalekit API Configuration](/.netlify/images?url=_astro%2F2.DW5ajBz2.png\&w=3380\&h=2474\&dpl=6aaa70ad2ea7b40008ad2afd) 3. #### Connect Firebase to Scalekit using your API credentials [Section titled “Connect Firebase to Scalekit using your API credentials”](#connect-firebase-to-scalekit-using-your-api-credentials) In Firebase Console, paste the Scalekit values into the corresponding fields: * **Client ID**: Paste your Scalekit Client ID * **Issuer URL**: Paste your Scalekit Environment URL * **Client Secret**: Paste your Scalekit Client Secret ![Firebase OIDC Provider Configuration](/.netlify/images?url=_astro%2F3.B8I5cBOV.png\&w=3380\&h=2474\&dpl=6aaa70ad2ea7b40008ad2afd) 4. #### Allow Firebase to redirect users back to your app [Section titled “Allow Firebase to redirect users back to your app”](#allow-firebase-to-redirect-users-back-to-your-app) Copy the **Callback URL** from your Firebase OIDC Integration settings. ![Firebase Callback URL](/.netlify/images?url=_astro%2F4.BgGZ4s_j.png\&w=3380\&h=2474\&dpl=6aaa70ad2ea7b40008ad2afd) Add this URL as a **Allowed Callback URI** in your Scalekit Authentication > Redirects section. ![Scalekit Redirect URI Configuration](/.netlify/images?url=_astro%2F5.Df1HXppc.png\&w=3380\&h=2474\&dpl=6aaa70ad2ea7b40008ad2afd) 5. #### Configure allowed callback URIs in Scalekit [Section titled “Configure allowed callback URIs in Scalekit”](#configure-allowed-callback-uris-in-scalekit) In your Scalekit Dashboard, navigate to **Authentication** > **Redirects** > **Allowed Callback URIs**. Add your Firebase callback URL to the allowed callback URIs list: * **For development**: `https://your-firebase-domain.com/__/auth/handler` * **For production**: `https://your-domain.com/__/auth/handler` 6. #### Add SSO login to your frontend code [Section titled “Add SSO login to your frontend code”](#add-sso-login-to-your-frontend-code) Use Firebase’s standard OIDC authentication in your frontend: Login Implementation ```javascript 1 import { getAuth, OAuthProvider, signInWithPopup } from 'firebase/auth'; 2 3 const auth = getAuth(); 4 5 // Initialize Scalekit as an OIDC provider 6 const scalekitProvider = new OAuthProvider('oidc.scalekit'); 7 8 // Set SSO parameters 9 scalekitProvider.setCustomParameters({ 10 domain: 'customer@company.com', // or organization_id, connection_id 11 }); 12 13 // Handle SSO login 14 const loginButton = document.getElementById('sso-login'); 15 loginButton.onclick = async () => { 16 try { 17 const result = await signInWithPopup(auth, scalekitProvider); 18 const user = result.user; 19 20 console.log('Authenticated user:', user.email); 21 // User is now signed in to Firebase 22 } catch (error) { 23 console.error('Authentication failed:', error); 24 } 25 }; ``` ## Option 2: Direct SSO with Custom Tokens [Section titled “Option 2: Direct SSO with Custom Tokens”](#option-2-direct-sso-with-custom-tokens) Use this approach if you have **Legacy Firebase Authentication** or need full control over the authentication flow. Your backend integrates directly with Scalekit and creates custom Firebase tokens. Your backend handles SSO authentication and creates custom tokens for Firebase. 1. #### Install Scalekit and Firebase Admin SDKs [Section titled “Install Scalekit and Firebase Admin SDKs”](#install-scalekit-and-firebase-admin-sdks) Install the Scalekit SDK and configure your backend server with Firebase Admin SDK: ```bash 1 npm install @scalekit-sdk/node firebase-admin ``` backend/server.js ```javascript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 import admin from 'firebase-admin'; 3 4 // Initialize Scalekit 5 const scalekit = new ScalekitClient( 6 process.env.SCALEKIT_ENVIRONMENT_URL, 7 process.env.SCALEKIT_CLIENT_ID, 8 process.env.SCALEKIT_CLIENT_SECRET 9 ); 10 11 // Initialize Firebase Admin ``` 2. #### Handle SSO callback and create Firebase tokens [Section titled “Handle SSO callback and create Firebase tokens”](#handle-sso-callback-and-create-firebase-tokens) Implement the SSO callback handler that exchanges the authorization code for user details and creates custom Firebase tokens: SSO Callback Handler ```javascript 1 app.get('/auth/callback', async (req, res) => { 2 const { code, error, error_description } = req.query; 3 4 if (error) { 5 return res.status(400).json({ 6 error: 'Authentication failed', 7 details: error_description 8 }); 9 } 10 11 try { 12 // Exchange code for user profile 13 const result = await scalekit.authenticateWithCode( 14 code, 15 'https://your-app.com/auth/callback' 16 ); 17 18 const user = result.user; 19 20 // Create custom Firebase token 21 const customToken = await admin.auth().createCustomToken(user.id, { 22 email: user.email, 23 name: `${user.givenName} ${user.familyName}`, 24 organizationId: user.organizationId, 25 }); 26 27 res.json({ 28 customToken, 29 user: { 30 email: user.email, 31 name: `${user.givenName} ${user.familyName}`, 32 } 33 }); 34 } catch (error) { 35 console.error('SSO authentication failed:', error); 36 res.status(500).json({ error: 'Internal server error' }); 37 } 38 }); ``` 3. #### Generate authorization URL to initiate SSO [Section titled “Generate authorization URL to initiate SSO”](#generate-authorization-url-to-initiate-sso) Create an endpoint to generate Scalekit authorization URLs: * Node.js Authorization URL Endpoint ```javascript 1 app.post('/auth/start-sso', async (req, res) => { 2 const { organizationId, domain, connectionId } = req.body; 3 4 try { 5 const options = {}; 6 if (organizationId) options.organizationId = organizationId; 7 if (domain) options.domain = domain; 8 if (connectionId) options.connectionId = connectionId; 9 10 const authorizationUrl = scalekit.getAuthorizationUrl( 11 'https://your-app.com/auth/callback', 12 options 13 ); 14 15 res.json({ authorizationUrl }); 16 } catch (error) { 17 console.error('Failed to generate authorization URL:', error); 18 res.status(500).json({ error: 'Internal server error' }); 19 } 20 }); ``` * Python Authorization URL Endpoint ```python 1 @app.route('/auth/start-sso', methods=['POST']) 2 def start_sso(): 3 data = request.get_json() 4 organization_id = data.get('organizationId') 5 domain = data.get('domain') 6 connection_id = data.get('connectionId') 7 8 try: 9 options = {} 10 if organization_id: 11 options['organization_id'] = organization_id 12 if domain: 13 options['domain'] = domain 14 if connection_id: 15 options['connection_id'] = connection_id 16 17 authorization_url = scalekit.get_authorization_url( 18 'https://your-app.com/auth/callback', 19 options 20 ) 21 22 return jsonify({'authorizationUrl': authorization_url}) 23 except Exception as e: 24 print(f'Failed to generate authorization URL: {e}') 25 return jsonify({'error': 'Internal server error'}), 500 ``` * Go Authorization URL Endpoint ```go 1 func startSSOHandler(w http.ResponseWriter, r *http.Request) { 2 var requestData struct { 3 OrganizationID string `json:"organizationId"` 4 Domain string `json:"domain"` 5 ConnectionID string `json:"connectionId"` 6 } 7 8 if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil { 9 http.Error(w, "Invalid request body", http.StatusBadRequest) 10 return 11 } 12 13 options := scalekit.AuthorizationUrlOptions{} 14 if requestData.OrganizationID != "" { 15 options.OrganizationId = requestData.OrganizationID 16 } 17 if requestData.Domain != "" { 18 options.Domain = requestData.Domain 19 } 20 if requestData.ConnectionID != "" { 21 options.ConnectionId = requestData.ConnectionID 22 } 23 24 authorizationURL := scalekitClient.GetAuthorizationUrl( 25 "https://your-app.com/auth/callback", 26 options, 27 ) 28 29 response := map[string]string{ 30 "authorizationUrl": authorizationURL, 31 } 32 33 w.Header().Set("Content-Type", "application/json") 34 json.NewEncoder(w).Encode(response) 35 } ``` * Java Authorization URL Endpoint ```java 1 @PostMapping("/auth/start-sso") 2 public ResponseEntity startSSO(@RequestBody Map request) { 3 String organizationId = request.get("organizationId"); 4 String domain = request.get("domain"); 5 String connectionId = request.get("connectionId"); 6 7 try { 8 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 9 if (organizationId != null) options.setOrganizationId(organizationId); 10 if (domain != null) options.setDomain(domain); 11 if (connectionId != null) options.setConnectionId(connectionId); 12 13 String authorizationUrl = scalekitClient.authentication() 14 .getAuthorizationUrl("https://your-app.com/auth/callback", options) 15 .toString(); 16 17 return ResponseEntity.ok(Map.of("authorizationUrl", authorizationUrl)); 18 } catch (Exception e) { 19 System.err.println("Failed to generate authorization URL: " + e.getMessage()); 20 return ResponseEntity.status(500).body(Map.of("error", "Internal server error")); 21 } 22 } ``` 4. #### Build frontend SSO flow with custom tokens [Section titled “Build frontend SSO flow with custom tokens”](#build-frontend-sso-flow-with-custom-tokens) Create the frontend flow that initiates SSO and handles the custom token: Frontend SSO Implementation ```javascript 1 import { getAuth, signInWithCustomToken } from 'firebase/auth'; 2 3 const auth = getAuth(); 4 5 // Initiate SSO flow 6 const initiateSSO = async () => { 7 try { 8 // Get authorization URL from your backend 9 const response = await fetch('/auth/start-sso', { 10 method: 'POST', 11 headers: { 'Content-Type': 'application/json' }, 12 body: JSON.stringify({ 13 organizationId: 'org_123456789', // or domain, connectionId 14 }), 15 }); 16 17 const { authorizationUrl } = await response.json(); 18 19 // Redirect to SSO 20 window.location.href = authorizationUrl; 21 } catch (error) { 22 console.error('Failed to initiate SSO:', error); 23 } 24 }; 25 26 // Handle SSO callback (call this on your callback page) 27 const handleSSOCallback = async () => { 28 const urlParams = new URLSearchParams(window.location.search); 29 const code = urlParams.get('code'); 30 const error = urlParams.get('error'); 31 32 if (error) { 33 console.error('SSO failed:', error); 34 return; 35 } 36 37 try { 38 // Exchange code for custom token 39 const response = await fetch(`/auth/callback?code=${code}`); 40 const { customToken, user } = await response.json(); 41 42 // Sign in to Firebase with custom token 43 const userCredential = await signInWithCustomToken(auth, customToken); 44 const firebaseUser = userCredential.user; 45 46 console.log('Successfully authenticated:', firebaseUser); 47 48 // Redirect to your app 49 window.location.href = '/dashboard'; 50 } catch (error) { 51 console.error('Authentication failed:', error); 52 } 53 }; ``` ## Handle identity provider-initiated SSO [Section titled “Handle identity provider-initiated SSO”](#handle-identity-provider-initiated-sso) Both approaches support IdP-initiated SSO, where users access your application directly from their identity provider portal. Create a dedicated endpoint to handle these requests. For detailed implementation instructions, refer to the [IdP-Initiated SSO guide](/sso/guides/idp-init-sso/). Both approaches provide secure, enterprise-grade SSO authentication while maintaining compatibility with Firebase’s ecosystem and features. --- # DOCUMENT BOUNDARY --- # Authenticate customer apps > Use Scalekit to implement OAuth for customer apps. Issue tokens and validate API requests with JWKS This guide explains how you enable API authentication for your customers’ applications using Scalekit’s OAuth 2.0 client credentials flow. When your customers build applications that need to access your API, they use client credentials registered through your Scalekit environment to obtain access tokens. Your API validates these tokens to authorize their requests using JWKS. ## How your customers’ applications authenticate with your API [Section titled “How your customers’ applications authenticate with your API”](#how-your-customers-applications-authenticate-with-your-api) Your Scalekit environment functions as an OAuth 2.0 Authorization Server. Your customers’ applications authenticate using the client credentials flow, exchanging their registered client ID and secret for access tokens that authorize API requests to your platform. ### Storing client credentials [Section titled “Storing client credentials”](#storing-client-credentials) Your customers’ applications securely store the credentials you issued to them in environment variables. This example shows how their applications would store these credentials: Environment variables in customer's application ```sh 1 YOURAPP_ENVIRONMENT_URL="" 2 YOURAPP_CLIENT_ID="" 3 YOURAPP_CLIENT_SECRET="" ``` These credentials are obtained when you register an API client for your customer (see the [quickstart guide](/authenticate/m2m/api-auth-quickstart/) for client registration). ### Obtaining access tokens [Section titled “Obtaining access tokens”](#obtaining-access-tokens) Your customers’ applications obtain access tokens from your Scalekit authorization server before making API requests. They send their credentials to your token endpoint: Token endpoint ```sh 1 https:///oauth/token ``` Here’s how your customers’ applications request access tokens: * cURL ```sh 1 curl -X POST \ 2 "https:///oauth/token" \ 3 -H "Content-Type: application/x-www-form-urlencoded" \ 4 -d "grant_type=client_credentials" \ 5 -d "client_id=" \ 6 -d "client_secret=" \ 7 -d "scope=openid profile email" ``` * Python ```python 1 import os 2 import json 3 import requests 4 5 # Customer's application configuration 6 env_url = os.environ['YOURAPP_SCALEKIT_ENVIRONMENT_URL'] 7 8 def get_m2m_access_token(): 9 """ 10 Customer's application requests an access token using client credentials. 11 This token will be used to authenticate API requests to your platform. 12 """ 13 headers = {"Content-Type": "application/x-www-form-urlencoded"} 14 params = { 15 "grant_type": "client_credentials", 16 "client_id": os.environ['YOURAPP_SCALEKIT_CLIENT_ID'], 17 "client_secret": os.environ['YOURAPP_SCALEKIT_CLIENT_SECRET'], 18 "scope": "openid profile email" 19 } 20 21 response = requests.post( 22 url=f"{env_url}/oauth/token", 23 headers=headers, 24 data=params, 25 verify=True 26 ) 27 28 access_token = response.json().get('access_token') 29 return access_token ``` Your authorization server returns a JSON response containing the access token: Token response ```json 1 { 2 "access_token": "", 3 "token_type": "Bearer", 4 "expires_in": 86399, 5 "scope": "openid" 6 } ``` | Field | Description | | -------------- | ----------------------------------------------------- | | `access_token` | Token for authenticating API requests | | `token_type` | Always “Bearer” for this flow | | `expires_in` | Token validity period in seconds (typically 24 hours) | | `scope` | Authorized scopes for this token | ### Using access tokens [Section titled “Using access tokens”](#using-access-tokens) After obtaining an access token, your customers’ applications include it in the Authorization header when making requests to your API: Customer's application making an API request ```sh 1 curl --request GET "https://" \ 2 -H "Content-Type: application/json" \ 3 -H "Authorization: Bearer " ``` ## Validating access tokens [Section titled “Validating access tokens”](#validating-access-tokens) Your API server must validate access tokens before processing requests. Scalekit uses JSON Web Tokens (JWTs) signed with RSA keys, which you validate using the JSON Web Key Set (JWKS) endpoint. ### Retrieving JWKS [Section titled “Retrieving JWKS”](#retrieving-jwks) Your application should fetch the public keys from the JWKS endpoint: JWKS endpoint ```sh 1 https:///keys ``` JWKS response ```json 1 { 2 "keys": [ 3 { 4 "use": "sig", 5 "kty": "RSA", 6 "kid": "snk_58327480989122566", 7 "alg": "RS256", 8 "n": "wUaqIj3pIE_zfGN9u4GySZs862F-0Kl-..", 9 "e": "AQAB" 10 } 11 ] 12 } ``` ### Token validation process [Section titled “Token validation process”](#token-validation-process) When your API receives a request with a JWT, follow these steps: 1. Extract the token from the Authorization header 2. Fetch the JWKS from the endpoint 3. Use the public key from JWKS to verify the token’s signature 4. Validate the token’s claims (issuer, audience, expiration) This example shows how to fetch JWKS data: Fetch JWKS with cURL ```sh 1 curl -s "https:///keys" | jq ``` * jwksClient (Node.js) Express.js ```javascript 1 const express = require('express'); 2 const jwt = require('jsonwebtoken'); 3 const jwksClient = require('jwks-rsa'); 4 const app = express(); 5 6 // Initialize JWKS client to validate tokens from customer applications 7 // This fetches public keys from your Scalekit environment 8 const client = jwksClient({ 9 jwksUri: `https:///keys` 10 }); 11 12 // Function to get signing key for token verification 13 function getKey(header, callback) { 14 client.getSigningKey(header.kid, function(err, key) { 15 if (err) return callback(err); 16 17 const signingKey = key.publicKey || key.rsaPublicKey; 18 callback(null, signingKey); 19 }); 20 } 21 22 // Middleware to validate JWT from customer's API client application 23 function validateJwt(req, res, next) { 24 // Extract token sent by customer's application 25 const authHeader = req.headers.authorization; 26 if (!authHeader || !authHeader.startsWith('Bearer ')) { 27 return res.status(401).json({ error: 'Missing authorization token' }); 28 } 29 30 const token = authHeader.split(' ')[1]; 31 32 // Verify the token signature using JWKS 33 jwt.verify(token, getKey, { 34 algorithms: ['RS256'] 35 }, (err, decoded) => { 36 if (err) { 37 return res.status(401).json({ error: 'Invalid token', details: err.message }); 38 } 39 40 // Token is valid - add decoded claims to request 41 req.user = decoded; 42 next(); 43 }); 44 } 45 46 // Apply validation middleware to your API routes 47 app.use('/api', validateJwt); 48 49 // Example protected API endpoint 50 app.get('/api/data', (req, res) => { 51 res.json({ 52 message: 'Customer application authenticated successfully', 53 userId: req.user.sub 54 }); 55 }); 56 57 app.listen(3000, () => { 58 console.log('API server running on port 3000'); 59 }); ``` * Python Flask ```python 1 from scalekit import ScalekitClient 2 import os 3 4 # Initialize Scalekit SDK to validate tokens from customer applications 5 scalekit_client = ScalekitClient( 6 env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), 7 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 8 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") 9 ) 10 11 def validate_api_request(request): 12 """ 13 Validate access token from customer's API client application. 14 Your API uses this to authorize requests from customer applications. 15 """ 16 # Extract token sent by customer's application 17 auth_header = request.headers.get('Authorization') 18 if not auth_header or not auth_header.startswith('Bearer '): 19 return None, "Missing authorization token" 20 21 token = auth_header.split(' ')[1] 22 23 try: 24 # Validate token and extract claims using Scalekit SDK 25 claims = scalekit_client.validate_access_token_and_get_claims( 26 token=token 27 ) 28 29 # Token is valid - return claims for authorization logic 30 return claims, None 31 except Exception as e: 32 return None, f"Invalid token: {str(e)}" 33 34 # Example: Use in your Flask API endpoint 35 @app.route('/api/data', methods=['GET']) 36 def get_data(): 37 claims, error = validate_api_request(request) 38 39 if error: 40 return {"error": error}, 401 41 42 # Customer application is authenticated 43 return { 44 "message": "Customer application authenticated successfully", 45 "userId": claims.get("sub") 46 } ``` ### SDK support status [Section titled “SDK support status”](#sdk-support-status) All Scalekit SDKs include helpers for validating access tokens: * **Node.js**: Provides `validateAccessToken` and `validateToken` methods with `TokenValidationOptions` for validating issuer, audience, and required scopes. * **Python**: Provides `validate_access_token`, `validate_token`, and `validate_access_token_and_get_claims` methods with `TokenValidationOptions` for validating issuer, audience, and required scopes. * **Go**: Provides `ValidateAccessToken`, generic `ValidateToken[T]`, and `GetAccessTokenClaims` helpers that validate tokens using JWKS and return typed claims with errors. These methods accept `context.Context` as the first argument for cancellation and timeout. * **Java**: Provides `validateAccessToken` (boolean) and `validateAccessTokenAndGetClaims` (returns claims and throws `APIException`) for token validation in JVM applications. You can still use standard JWT libraries with the JWKS endpoint, as shown in the examples above, when you need custom validation logic or cannot use an SDK in your API service. --- # DOCUMENT BOUNDARY --- # Bring your own email provider > Scalekit allows you to configure your own email provider to improve deliverability and security. Email delivery is a critical part of your authentication flow. By default, Scalekit sends all authentication emails (sign-in verification, sign-up confirmation, password reset) through its own email service. However, for production applications, you may need more control over email branding, deliverability, and compliance requirements. Here are common scenarios where you’ll want to customize email delivery: * **Brand consistency**: Send emails from your company’s domain with your own sender name and email address to maintain brand trust * **Deliverability optimization**: Use your established email reputation and delivery infrastructure to improve inbox placement * **Compliance requirements**: Meet specific regulatory or organizational requirements for email handling and data sovereignty * **Email analytics**: Track email metrics and performance through your existing email service provider * **Custom domains**: Ensure emails come from your verified domain to avoid spam filters and build user trust * **Enterprise requirements**: Corporate customers may require emails to come from verified business domains Scalekit provides two approaches to handle email delivery, allowing you to choose the right balance between simplicity and control. ![Email delivery methods in Scalekit](/.netlify/images?url=_astro%2F1-email-delivery-method.DLKX49XJ.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) ## Use Scalekit’s managed email service Default [Section titled “Use Scalekit’s managed email service ”](#use-scalekits-managed-email-service-) The simplest approach requires no configuration. Scalekit handles all email delivery using its own infrastructure. **When to use this approach:** * Quick setup for development and testing * You don’t need custom branding * You want Scalekit to handle email deliverability **Default settings:** * **Sender Name**: Team workspace\_name * **From Email Address**: * **Infrastructure**: Fully managed by Scalekit No additional configuration is required. Your authentication emails will be sent automatically with these settings. ## Configure your own email provider [Section titled “Configure your own email provider”](#configure-your-own-email-provider) For production applications, you’ll likely want to use your own email provider to maintain brand consistency and control deliverability. When to use this approach: * You need emails sent from your domain * You want complete control over email deliverability * You need to meet compliance requirements (e.g. GDPR, CCPA) * You want to integrate with existing email analytics ### Gather your SMTP credentials [Section titled “Gather your SMTP credentials”](#gather-your-smtp-credentials) Before configuring, collect the following information from your email provider: | Field | Description | | -------------------- | ------------------------------------------ | | **SMTP Server Host** | Your provider’s SMTP hostname | | **SMTP Port** | Usually 587 (TLS) or 465 (SSL) | | **SMTP Username** | Your authentication username | | **SMTP Password** | Your authentication password | | **Sender Email** | The email address emails will be sent from | | **Sender Name** | The display name recipients will see | ### Configure SMTP settings in Scalekit [Section titled “Configure SMTP settings in Scalekit”](#configure-smtp-settings-in-scalekit) 1. Navigate to email settings In your Scalekit dashboard, go to **Emails**. 2. Select custom email provider Choose **Use your own email provider** from the email delivery options 3. Configure sender information ```plaintext 1 From Email Address: noreply@yourdomain.com 2 Sender Name: Your Company Name ``` 4. Enter SMTP configuration ```plaintext 1 SMTP Server Host: smtp.your-provider.com 2 SMTP Port: 587 3 SMTP Username: your-username 4 SMTP Password: your-password ``` 5. Save and test configuration Click **Save** to apply your settings, then send a test email to verify the configuration ### Common provider configurations [Section titled “Common provider configurations”](#common-provider-configurations) * SendGrid ```plaintext 1 Host: smtp.sendgrid.net 2 Port: 587 3 Username: apikey 4 Password: [Your SendGrid API Key] ``` * Amazon SES ```plaintext 1 Host: email-smtp.us-east-1.amazonaws.com 2 Port: 587 3 Username: [Your SMTP Username from AWS] 4 Password: [Your SMTP Password from AWS] ``` * Postmark ```plaintext 1 Host: smtp.postmarkapp.com 2 Port: 587 3 Username: [Your Postmark Server Token] 4 Password: [Your Postmark Server Token] ``` ## Test your email configuration [Section titled “Test your email configuration”](#test-your-email-configuration) After configuring your email provider, verify that everything works correctly: 1. Send a test email through your authentication flow 2. Check delivery to ensure emails reach the intended recipients 3. Verify sender information appears correctly in the recipient’s inbox 4. Confirm formatting, branding, links and buttons work as expected --- # DOCUMENT BOUNDARY --- # Authentication best practices > Security best practices for authentication implementation, including threat modeling, advanced patterns, and security checklists. This guide covers security best practices for implementing authentication with Scalekit. Use it for threat modeling, advanced security patterns, and production-ready configurations. ## Security threat model [Section titled “Security threat model”](#security-threat-model) ### Common authentication threats [Section titled “Common authentication threats”](#common-authentication-threats) Identify potential security threats to implement appropriate countermeasures: | Threat | Description | Mitigation | | -------------------- | ------------------------------------------------------------ | ------------------------------------------------- | | **CSRF attacks** | Malicious requests executed on behalf of authenticated users | Use `state` parameter, validate origins | | **Token theft** | Access tokens intercepted or stolen | Secure storage, short lifetimes, refresh rotation | | **Session fixation** | Attacker fixes session ID before authentication | Regenerate sessions, secure cookies | | **Phishing** | Users tricked into entering credentials on fake sites | Domain validation, HTTPS enforcement | | **Replay attacks** | Intercepted requests replayed by attackers | Nonces, timestamps, request signing | ### Multi-tenant security considerations [Section titled “Multi-tenant security considerations”](#multi-tenant-security-considerations) B2B applications face additional security challenges: * **Tenant isolation** - Prevent data leakage between organizations * **Admin privilege escalation** - Secure organization admin roles * **SSO configuration tampering** - Protect identity provider settings * **Cross-tenant user enumeration** - Prevent user discovery across organizations ## Advanced security patterns [Section titled “Advanced security patterns”](#advanced-security-patterns) ### Dynamic security policy enforcement [Section titled “Dynamic security policy enforcement”](#dynamic-security-policy-enforcement) Apply organization-specific security policies: * Node.js Dynamic security policies ```javascript 1 // Apply organization-specific security requirements 2 async function createAuthorizationUrl(orgId, userEmail) { 3 const redirectUri = 'https://yourapp.com/auth/callback'; 4 5 // Fetch organization security policy 6 const securityPolicy = await getSecurityPolicy(orgId); 7 8 // Apply conditional authentication requirements 9 const options = { 10 scopes: ['openid', 'profile', 'email', 'offline_access'], 11 organizationId: orgId, 12 loginHint: userEmail, 13 state: generateSecureState(), 14 15 // Force re-authentication for high-security orgs 16 prompt: securityPolicy.requireReauth ? 'login' : undefined, 17 maxAge: securityPolicy.maxSessionAge || 3600, 18 acrValues: securityPolicy.requiredAuthLevel || 'aal1' 19 }; 20 21 return scalekit.getAuthorizationUrl(redirectUri, options); 22 } ``` * Python Dynamic security policies ```python 1 # Apply organization-specific security requirements 2 async def create_authorization_url(org_id, user_email): 3 redirect_uri = 'https://yourapp.com/auth/callback' 4 5 # Fetch organization security policy 6 security_policy = await get_security_policy(org_id) 7 8 # Apply conditional authentication requirements 9 options = AuthorizationUrlOptions() 10 options.scopes = ['openid', 'profile', 'email', 'offline_access'] 11 options.organization_id = org_id 12 options.login_hint = user_email 13 options.state = generate_secure_state() 14 15 # Force re-authentication for high-security orgs 16 if security_policy.require_reauth: 17 options.prompt = 'login' 18 options.max_age = security_policy.max_session_age or 3600 19 options.acr_values = security_policy.required_auth_level or 'aal1' 20 21 return scalekit_client.get_authorization_url(redirect_uri, options) ``` * Go Dynamic security policies ```go 1 // Apply organization-specific security requirements 2 func createAuthorizationUrl(orgId, userEmail string) (string, error) { 3 redirectUri := "https://yourapp.com/auth/callback" 4 5 // Fetch organization security policy 6 securityPolicy, err := getSecurityPolicy(orgId) 7 if err != nil { 8 return "", err 9 } 10 11 // Apply conditional authentication requirements 12 options := scalekit.AuthorizationUrlOptions{ 13 Scopes: []string{"openid", "profile", "email", "offline_access"}, 14 OrganizationId: orgId, 15 LoginHint: userEmail, 16 State: generateSecureState(), 17 18 // Force re-authentication for high-security orgs 19 Prompt: conditionalPrompt(securityPolicy.RequireReauth), 20 MaxAge: securityPolicy.MaxSessionAge, 21 AcrValues: securityPolicy.RequiredAuthLevel, 22 } 23 24 authUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options) 25 return authUrl.String(), err 26 } ``` * Java Dynamic security policies ```java 1 // Apply organization-specific security requirements 2 public String createAuthorizationUrl(String orgId, String userEmail) { 3 String redirectUri = "https://yourapp.com/auth/callback"; 4 5 // Fetch organization security policy 6 SecurityPolicy securityPolicy = getSecurityPolicy(orgId); 7 8 // Apply conditional authentication requirements 9 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 10 options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access")); 11 options.setOrganizationId(orgId); 12 options.setLoginHint(userEmail); 13 options.setState(generateSecureState()); 14 15 // Force re-authentication for high-security orgs 16 if (securityPolicy.isRequireReauth()) { 17 options.setPrompt("login"); 18 } 19 options.setMaxAge(securityPolicy.getMaxSessionAge()); 20 options.setAcrValues(securityPolicy.getRequiredAuthLevel()); 21 22 URL authUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options); 23 return authUrl.toString(); 24 } ``` ### Request signing and validation [Section titled “Request signing and validation”](#request-signing-and-validation) Verify request integrity with signatures: * Node.js Request signing ```javascript 1 const crypto = require('crypto'); 2 3 // Sign sensitive requests with HMAC 4 function signRequest(payload, secret) { 5 const timestamp = Date.now().toString(); 6 const nonce = crypto.randomBytes(16).toString('hex'); 7 8 // Create signature payload 9 const signaturePayload = `${timestamp}.${nonce}.${JSON.stringify(payload)}`; 10 const signature = crypto 11 .createHmac('sha256', secret) 12 .update(signaturePayload) 13 .digest('hex'); 14 15 return { 16 payload, 17 timestamp, 18 nonce, 19 signature: `sha256=${signature}` 20 }; 21 } 22 23 // Verify request signatures 24 function verifyRequest(receivedPayload, receivedSignature, secret, maxAge = 300) { 25 const [timestamp, nonce, payload] = receivedPayload.split('.'); 26 27 // Check timestamp to prevent replay attacks 28 if (Date.now() - parseInt(timestamp) > maxAge * 1000) { 29 throw new Error('Request timestamp too old'); 30 } 31 32 // Verify signature 33 const expectedPayload = `${timestamp}.${nonce}.${payload}`; 34 const expectedSignature = crypto 35 .createHmac('sha256', secret) 36 .update(expectedPayload) 37 .digest('hex'); 38 39 if (!crypto.timingSafeEqual( 40 Buffer.from(receivedSignature, 'hex'), 41 Buffer.from(`sha256=${expectedSignature}`, 'hex') 42 )) { 43 throw new Error('Invalid signature'); 44 } 45 46 return JSON.parse(payload); 47 } ``` * Python Request signing ```python 1 import hmac 2 import hashlib 3 import json 4 import time 5 import secrets 6 7 # Sign sensitive requests with HMAC 8 def sign_request(payload, secret): 9 timestamp = str(int(time.time() * 1000)) 10 nonce = secrets.token_hex(16) 11 12 # Create signature payload 13 signature_payload = f"{timestamp}.{nonce}.{json.dumps(payload)}" 14 signature = hmac.new( 15 secret.encode(), 16 signature_payload.encode(), 17 hashlib.sha256 18 ).hexdigest() 19 20 return { 21 'payload': payload, 22 'timestamp': timestamp, 23 'nonce': nonce, 24 'signature': f"sha256={signature}" 25 } 26 27 # Verify request signatures 28 def verify_request(received_payload, received_signature, secret, max_age=300): 29 timestamp, nonce, payload = received_payload.split('.') 30 31 # Check timestamp to prevent replay attacks 32 if time.time() * 1000 - int(timestamp) > max_age * 1000: 33 raise ValueError('Request timestamp too old') 34 35 # Verify signature 36 expected_payload = f"{timestamp}.{nonce}.{payload}" 37 expected_signature = hmac.new( 38 secret.encode(), 39 expected_payload.encode(), 40 hashlib.sha256 41 ).hexdigest() 42 43 if not hmac.compare_digest( 44 received_signature, 45 f"sha256={expected_signature}" 46 ): 47 raise ValueError('Invalid signature') 48 49 return json.loads(payload) ``` * Go Request signing ```go 1 import ( 2 "crypto/hmac" 3 "crypto/rand" 4 "crypto/sha256" 5 "encoding/hex" 6 "encoding/json" 7 "fmt" 8 "time" 9 ) 10 11 // Sign sensitive requests with HMAC 12 func signRequest(payload interface{}, secret string) (map[string]interface{}, error) { 13 timestamp := fmt.Sprintf("%d", time.Now().UnixMilli()) 14 15 nonceBytes := make([]byte, 16) 16 rand.Read(nonceBytes) 17 nonce := hex.EncodeToString(nonceBytes) 18 19 // Create signature payload 20 payloadJSON, _ := json.Marshal(payload) 21 signaturePayload := fmt.Sprintf("%s.%s.%s", timestamp, nonce, payloadJSON) 22 23 h := hmac.New(sha256.New, []byte(secret)) 24 h.Write([]byte(signaturePayload)) 25 signature := hex.EncodeToString(h.Sum(nil)) 26 27 return map[string]interface{}{ 28 "payload": payload, 29 "timestamp": timestamp, 30 "nonce": nonce, 31 "signature": fmt.Sprintf("sha256=%s", signature), 32 }, nil 33 } 34 35 // Verify request signatures 36 func verifyRequest(receivedPayload, receivedSignature, secret string, maxAge int64) (interface{}, error) { 37 // Parse payload components 38 parts := strings.Split(receivedPayload, ".") 39 if len(parts) != 3 { 40 return nil, fmt.Errorf("invalid payload format") 41 } 42 43 timestamp, err := strconv.ParseInt(parts[0], 10, 64) 44 if err != nil { 45 return nil, fmt.Errorf("invalid timestamp") 46 } 47 48 // Check timestamp to prevent replay attacks 49 if time.Now().UnixMilli()-timestamp > maxAge*1000 { 50 return nil, fmt.Errorf("request timestamp too old") 51 } 52 53 // Verify signature 54 expectedPayload := receivedPayload 55 h := hmac.New(sha256.New, []byte(secret)) 56 h.Write([]byte(expectedPayload)) 57 expectedSignature := fmt.Sprintf("sha256=%s", hex.EncodeToString(h.Sum(nil))) 58 59 if !hmac.Equal([]byte(receivedSignature), []byte(expectedSignature)) { 60 return nil, fmt.Errorf("invalid signature") 61 } 62 63 var payload interface{} 64 if err := json.Unmarshal([]byte(parts[2]), &payload); err != nil { 65 return nil, fmt.Errorf("invalid payload JSON") 66 } 67 68 return payload, nil 69 } ``` * Java Request signing ```java 1 import javax.crypto.Mac; 2 import javax.crypto.spec.SecretKeySpec; 3 import java.security.SecureRandom; 4 import java.nio.charset.StandardCharsets; 5 import java.util.HashMap; 6 import java.util.Map; 7 8 // Sign sensitive requests with HMAC 9 public Map signRequest(Object payload, String secret) throws Exception { 10 String timestamp = String.valueOf(System.currentTimeMillis()); 11 12 SecureRandom random = new SecureRandom(); 13 byte[] nonceBytes = new byte[16]; 14 random.nextBytes(nonceBytes); 15 String nonce = bytesToHex(nonceBytes); 16 17 // Create signature payload 18 String payloadJson = objectMapper.writeValueAsString(payload); 19 String signaturePayload = timestamp + "." + nonce + "." + payloadJson; 20 21 Mac mac = Mac.getInstance("HmacSHA256"); 22 SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); 23 mac.init(secretKey); 24 byte[] signatureBytes = mac.doFinal(signaturePayload.getBytes(StandardCharsets.UTF_8)); 25 String signature = "sha256=" + bytesToHex(signatureBytes); 26 27 Map result = new HashMap<>(); 28 result.put("payload", payload); 29 result.put("timestamp", timestamp); 30 result.put("nonce", nonce); 31 result.put("signature", signature); 32 33 return result; 34 } 35 36 // Verify request signatures 37 public Object verifyRequest(String receivedPayload, String receivedSignature, 38 String secret, long maxAge) throws Exception { 39 String[] parts = receivedPayload.split("\\."); 40 if (parts.length != 3) { 41 throw new SecurityException("Invalid payload format"); 42 } 43 44 long timestamp = Long.parseLong(parts[0]); 45 46 // Check timestamp to prevent replay attacks 47 if (System.currentTimeMillis() - timestamp > maxAge * 1000) { 48 throw new SecurityException("Request timestamp too old"); 49 } 50 51 // Verify signature 52 Mac mac = Mac.getInstance("HmacSHA256"); 53 SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); 54 mac.init(secretKey); 55 byte[] expectedSignatureBytes = mac.doFinal(receivedPayload.getBytes(StandardCharsets.UTF_8)); 56 String expectedSignature = "sha256=" + bytesToHex(expectedSignatureBytes); 57 58 if (!MessageDigest.isEqual( 59 receivedSignature.getBytes(StandardCharsets.UTF_8), 60 expectedSignature.getBytes(StandardCharsets.UTF_8) 61 )) { 62 throw new SecurityException("Invalid signature"); 63 } 64 65 return objectMapper.readValue(parts[2], Object.class); 66 } ``` ## Secure token management [Section titled “Secure token management”](#secure-token-management) ### Token storage strategies [Section titled “Token storage strategies”](#token-storage-strategies) Select storage methods based on your application architecture: | Storage Method | Security Level | Use Case | Considerations | | --------------------- | -------------- | ------------------- | -------------------------------------- | | **HTTP-only cookies** | High | Web applications | Prevents XSS, requires CSRF protection | | **Secure memory** | High | Mobile/desktop apps | Cleared on app termination | | **Encrypted storage** | Medium | Persistent sessions | Key management complexity | | **LocalStorage** | Low | Not recommended | Vulnerable to XSS attacks | ### Token rotation implementation [Section titled “Token rotation implementation”](#token-rotation-implementation) Implement secure refresh token rotation: * Node.js Token rotation ```javascript 1 // Secure token refresh with rotation 2 async function refreshAccessToken(refreshToken, userId) { 3 try { 4 // Exchange refresh token for new tokens 5 const tokenResponse = await scalekit.exchangeCodeForTokens({ 6 refresh_token: refreshToken, 7 grant_type: 'refresh_token' 8 }); 9 10 // Store new tokens securely 11 const newTokens = { 12 accessToken: tokenResponse.access_token, 13 refreshToken: tokenResponse.refresh_token, // New refresh token 14 expiresAt: Date.now() + (tokenResponse.expires_in * 1000), 15 refreshExpiresAt: Date.now() + (30 * 24 * 60 * 60 * 1000) // 30 days 16 }; 17 18 // Update token storage atomically 19 await updateUserTokens(userId, newTokens); 20 21 // Invalidate old refresh token 22 await invalidateRefreshToken(refreshToken); 23 24 return newTokens; 25 26 } catch (error) { 27 // Handle refresh failure 28 if (error.code === 'invalid_grant') { 29 // Refresh token expired or revoked 30 await logoutUser(userId); 31 throw new Error('Session expired, please login again'); 32 } 33 34 // Log security event 35 await logSecurityEvent('token_refresh_failed', { 36 userId, 37 error: error.message, 38 timestamp: new Date().toISOString() 39 }); 40 41 throw error; 42 } 43 } 44 45 // Automatic token refresh middleware 46 function autoRefreshMiddleware(req, res, next) { 47 const { accessToken, refreshToken, expiresAt } = req.session.tokens || {}; 48 49 // Check if token expires within 5 minutes 50 if (accessToken && Date.now() + (5 * 60 * 1000) >= expiresAt) { 51 refreshAccessToken(refreshToken, req.session.userId) 52 .then(newTokens => { 53 req.session.tokens = newTokens; 54 next(); 55 }) 56 .catch(error => { 57 // Clear session on refresh failure 58 req.session.destroy(); 59 res.status(401).json({ error: 'Authentication required' }); 60 }); 61 } else { 62 next(); 63 } 64 } ``` * Python Token rotation ```python 1 import asyncio 2 from datetime import datetime, timedelta 3 4 # Secure token refresh with rotation 5 async def refresh_access_token(refresh_token, user_id): 6 try: 7 # Exchange refresh token for new tokens 8 token_response = await scalekit_client.exchange_code_for_tokens({ 9 'refresh_token': refresh_token, 10 'grant_type': 'refresh_token' 11 }) 12 13 # Store new tokens securely 14 new_tokens = { 15 'access_token': token_response['access_token'], 16 'refresh_token': token_response['refresh_token'], # New refresh token 17 'expires_at': datetime.now() + timedelta(seconds=token_response['expires_in']), 18 'refresh_expires_at': datetime.now() + timedelta(days=30) 19 } 20 21 # Update token storage atomically 22 await update_user_tokens(user_id, new_tokens) 23 24 # Invalidate old refresh token 25 await invalidate_refresh_token(refresh_token) 26 27 return new_tokens 28 29 except Exception as error: 30 # Handle refresh failure 31 if hasattr(error, 'code') and error.code == 'invalid_grant': 32 # Refresh token expired or revoked 33 await logout_user(user_id) 34 raise Exception('Session expired, please login again') 35 36 # Log security event 37 await log_security_event('token_refresh_failed', { 38 'user_id': user_id, 39 'error': str(error), 40 'timestamp': datetime.now().isoformat() 41 }) 42 43 raise error 44 45 # Automatic token refresh decorator 46 def auto_refresh_tokens(func): 47 async def wrapper(*args, **kwargs): 48 request = kwargs.get('request') or args[0] 49 tokens = getattr(request.session, 'tokens', {}) 50 51 access_token = tokens.get('access_token') 52 refresh_token = tokens.get('refresh_token') 53 expires_at = tokens.get('expires_at') 54 55 # Check if token expires within 5 minutes 56 if access_token and expires_at and datetime.now() + timedelta(minutes=5) >= expires_at: 57 try: 58 new_tokens = await refresh_access_token(refresh_token, request.session.user_id) 59 request.session.tokens = new_tokens 60 except Exception: 61 # Clear session on refresh failure 62 request.session.clear() 63 raise AuthenticationError('Authentication required') 64 65 return await func(*args, **kwargs) 66 return wrapper ``` * Go Token rotation ```go 1 import ( 2 "context" 3 "fmt" 4 "time" 5 ) 6 7 type TokenSet struct { 8 AccessToken string `json:"access_token"` 9 RefreshToken string `json:"refresh_token"` 10 ExpiresAt time.Time `json:"expires_at"` 11 RefreshExpiresAt time.Time `json:"refresh_expires_at"` 12 } 13 14 // Secure token refresh with rotation 15 func refreshAccessToken(ctx context.Context, refreshToken, userID string) (*TokenSet, error) { 16 // Exchange refresh token for new tokens 17 tokenResponse, err := scalekit.ExchangeCodeForTokens(ctx, &scalekit.TokenRequest{ 18 RefreshToken: refreshToken, 19 GrantType: "refresh_token", 20 }) 21 if err != nil { 22 return nil, fmt.Errorf("token exchange failed: %w", err) 23 } 24 25 // Store new tokens securely 26 newTokens := &TokenSet{ 27 AccessToken: tokenResponse.AccessToken, 28 RefreshToken: tokenResponse.RefreshToken, // New refresh token 29 ExpiresAt: time.Now().Add(time.Duration(tokenResponse.ExpiresIn) * time.Second), 30 RefreshExpiresAt: time.Now().Add(30 * 24 * time.Hour), // 30 days 31 } 32 33 // Update token storage atomically 34 if err := updateUserTokens(ctx, userID, newTokens); err != nil { 35 return nil, fmt.Errorf("failed to update tokens: %w", err) 36 } 37 38 // Invalidate old refresh token 39 if err := invalidateRefreshToken(ctx, refreshToken); err != nil { 40 // Log but don't fail the operation 41 logSecurityEvent(ctx, "refresh_token_invalidation_failed", map[string]interface{}{ 42 "user_id": userID, 43 "error": err.Error(), 44 }) 45 } 46 47 return newTokens, nil 48 } 49 50 // Automatic token refresh middleware 51 func autoRefreshMiddleware(next http.Handler) http.Handler { 52 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 53 session := getSession(r) 54 tokens := session.Tokens 55 56 // Check if token expires within 5 minutes 57 if tokens != nil && time.Until(tokens.ExpiresAt) <= 5*time.Minute { 58 newTokens, err := refreshAccessToken(r.Context(), tokens.RefreshToken, session.UserID) 59 if err != nil { 60 // Clear session on refresh failure 61 clearSession(w, r) 62 http.Error(w, "Authentication required", http.StatusUnauthorized) 63 return 64 } 65 66 session.Tokens = newTokens 67 saveSession(w, r, session) 68 } 69 70 next.ServeHTTP(w, r) 71 }) 72 } ``` * Java Token rotation ```java 1 import java.time.Instant; 2 import java.time.temporal.ChronoUnit; 3 import java.util.concurrent.CompletableFuture; 4 5 public class TokenSet { 6 private String accessToken; 7 private String refreshToken; 8 private Instant expiresAt; 9 private Instant refreshExpiresAt; 10 11 // constructors, getters, setters... 12 } 13 14 // Secure token refresh with rotation 15 public CompletableFuture refreshAccessToken(String refreshToken, String userId) { 16 return CompletableFuture.supplyAsync(() -> { 17 try { 18 // Exchange refresh token for new tokens 19 TokenResponse tokenResponse = scalekit.authentication() 20 .exchangeCodeForTokens(TokenRequest.builder() 21 .refreshToken(refreshToken) 22 .grantType("refresh_token") 23 .build()); 24 25 // Store new tokens securely 26 TokenSet newTokens = new TokenSet(); 27 newTokens.setAccessToken(tokenResponse.getAccessToken()); 28 newTokens.setRefreshToken(tokenResponse.getRefreshToken()); // New refresh token 29 newTokens.setExpiresAt(Instant.now().plusSeconds(tokenResponse.getExpiresIn())); 30 newTokens.setRefreshExpiresAt(Instant.now().plus(30, ChronoUnit.DAYS)); 31 32 // Update token storage atomically 33 updateUserTokens(userId, newTokens); 34 35 // Invalidate old refresh token 36 invalidateRefreshToken(refreshToken); 37 38 return newTokens; 39 40 } catch (Exception e) { 41 // Handle refresh failure 42 if (e instanceof InvalidGrantException) { 43 // Refresh token expired or revoked 44 logoutUser(userId); 45 throw new AuthenticationException("Session expired, please login again"); 46 } 47 48 // Log security event 49 logSecurityEvent("token_refresh_failed", Map.of( 50 "user_id", userId, 51 "error", e.getMessage(), 52 "timestamp", Instant.now().toString() 53 )); 54 55 throw new RuntimeException(e); 56 } 57 }); 58 } 59 60 // Automatic token refresh interceptor 61 @Component 62 public class AutoRefreshInterceptor implements HandlerInterceptor { 63 64 @Override 65 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 66 Object handler) throws Exception { 67 HttpSession session = request.getSession(false); 68 if (session == null) return true; 69 70 TokenSet tokens = (TokenSet) session.getAttribute("tokens"); 71 if (tokens == null) return true; 72 73 // Check if token expires within 5 minutes 74 if (tokens.getExpiresAt().minus(5, ChronoUnit.MINUTES).isBefore(Instant.now())) { 75 try { 76 String userId = (String) session.getAttribute("userId"); 77 TokenSet newTokens = refreshAccessToken(tokens.getRefreshToken(), userId).get(); 78 session.setAttribute("tokens", newTokens); 79 } catch (Exception e) { 80 // Clear session on refresh failure 81 session.invalidate(); 82 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 83 response.getWriter().write("{\"error\":\"Authentication required\"}"); 84 return false; 85 } 86 } 87 88 return true; 89 } 90 } ``` ## Security monitoring and incident response [Section titled “Security monitoring and incident response”](#security-monitoring-and-incident-response) ### Security event logging [Section titled “Security event logging”](#security-event-logging) Log security events for monitoring and analysis: security-events.js ```javascript 1 // Define security event types 2 const SECURITY_EVENTS = { 3 LOGIN_SUCCESS: 'login_success', 4 LOGIN_FAILURE: 'login_failure', 5 TOKEN_REFRESH: 'token_refresh', 6 SUSPICIOUS_ACTIVITY: 'suspicious_activity', 7 PRIVILEGE_ESCALATION: 'privilege_escalation', 8 DATA_ACCESS: 'sensitive_data_access' 9 }; 10 11 // Security event logger 12 async function logSecurityEvent(eventType, details) { 13 const event = { 14 type: eventType, 15 timestamp: new Date().toISOString(), 16 severity: getSeverityLevel(eventType), 17 details: { 18 ...details, 19 userAgent: details.userAgent, 20 ipAddress: details.ipAddress, 21 sessionId: details.sessionId 22 } 23 }; 24 25 // Store in security log 26 await securityLogger.log(event); 27 28 // Trigger alerts for high-severity events 29 if (event.severity === 'HIGH' || event.severity === 'CRITICAL') { 30 await triggerSecurityAlert(event); 31 } 32 } 33 34 // Anomaly detection 35 async function detectAnomalies(userId, loginEvent) { 36 const recentLogins = await getRecentLogins(userId, '24h'); 37 38 // Check for unusual patterns 39 const anomalies = []; 40 41 // Geographic anomaly 42 if (isUnusualLocation(loginEvent.location, recentLogins)) { 43 anomalies.push('unusual_location'); 44 } 45 46 // Time-based anomaly 47 if (isUnusualTime(loginEvent.timestamp, recentLogins)) { 48 anomalies.push('unusual_time'); 49 } 50 51 // Device anomaly 52 if (isUnusualDevice(loginEvent.device, recentLogins)) { 53 anomalies.push('unusual_device'); 54 } 55 56 if (anomalies.length > 0) { 57 await logSecurityEvent(SECURITY_EVENTS.SUSPICIOUS_ACTIVITY, { 58 userId, 59 anomalies, 60 loginEvent 61 }); 62 } 63 64 return anomalies; 65 } ``` ### Rate limiting and abuse prevention [Section titled “Rate limiting and abuse prevention”](#rate-limiting-and-abuse-prevention) Apply rate limiting to prevent abuse: * Node.js Advanced rate limiting ```javascript 1 // Multi-tier rate limiting 2 class SecurityRateLimiter { 3 constructor() { 4 this.limits = { 5 // Per-IP limits 6 login_attempts: { window: 900, max: 10 }, // 10 attempts per 15 min 7 token_requests: { window: 3600, max: 100 }, // 100 requests per hour 8 9 // Per-user limits 10 user_login_attempts: { window: 3600, max: 5 }, // 5 attempts per hour 11 user_token_refresh: { window: 3600, max: 50 }, // 50 refreshes per hour 12 13 // Global limits 14 total_requests: { window: 60, max: 10000 } // 10k requests per minute 15 }; 16 } 17 18 async checkLimit(type, identifier, customLimit = null) { 19 const limit = customLimit || this.limits[type]; 20 if (!limit) return { allowed: true }; 21 22 const key = `${type}:${identifier}`; 23 const current = await redis.get(key) || 0; 24 25 if (current >= limit.max) { 26 await this.logRateLimitExceeded(type, identifier, current); 27 return { 28 allowed: false, 29 retryAfter: await redis.ttl(key), 30 current: current, 31 max: limit.max 32 }; 33 } 34 35 // Increment counter with expiration 36 await redis.multi() 37 .incr(key) 38 .expire(key, limit.window) 39 .exec(); 40 41 return { allowed: true, current: current + 1, max: limit.max }; 42 } 43 44 // Dynamic rate limiting based on risk 45 async getDynamicLimit(type, riskScore) { 46 const baseLimit = this.limits[type]; 47 if (riskScore > 0.8) { 48 return { ...baseLimit, max: Math.floor(baseLimit.max * 0.2) }; 49 } else if (riskScore > 0.6) { 50 return { ...baseLimit, max: Math.floor(baseLimit.max * 0.5) }; 51 } 52 return baseLimit; 53 } 54 } 55 56 // Rate limiting middleware 57 async function rateLimitMiddleware(req, res, next) { 58 const limiter = new SecurityRateLimiter(); 59 const clientIP = req.ip; 60 const userId = req.session?.userId; 61 62 // Check IP-based limits 63 const ipLimit = await limiter.checkLimit('login_attempts', clientIP); 64 if (!ipLimit.allowed) { 65 return res.status(429).json({ 66 error: 'Too many requests', 67 retryAfter: ipLimit.retryAfter 68 }); 69 } 70 71 // Check user-based limits if authenticated 72 if (userId) { 73 const userLimit = await limiter.checkLimit('user_login_attempts', userId); 74 if (!userLimit.allowed) { 75 return res.status(429).json({ 76 error: 'Too many login attempts', 77 retryAfter: userLimit.retryAfter 78 }); 79 } 80 } 81 82 next(); 83 } ``` * Python Advanced rate limiting ```python 1 import asyncio 2 import time 3 from typing import Dict, Optional 4 5 class SecurityRateLimiter: 6 def __init__(self): 7 self.limits = { 8 # Per-IP limits 9 'login_attempts': {'window': 900, 'max': 10}, # 10 attempts per 15 min 10 'token_requests': {'window': 3600, 'max': 100}, # 100 requests per hour 11 12 # Per-user limits 13 'user_login_attempts': {'window': 3600, 'max': 5}, # 5 attempts per hour 14 'user_token_refresh': {'window': 3600, 'max': 50}, # 50 refreshes per hour 15 16 # Global limits 17 'total_requests': {'window': 60, 'max': 10000} # 10k requests per minute 18 } 19 20 async def check_limit(self, limit_type: str, identifier: str, custom_limit: Optional[Dict] = None): 21 limit = custom_limit or self.limits.get(limit_type) 22 if not limit: 23 return {'allowed': True} 24 25 key = f"{limit_type}:{identifier}" 26 current = await redis.get(key) or 0 27 current = int(current) 28 29 if current >= limit['max']: 30 await self.log_rate_limit_exceeded(limit_type, identifier, current) 31 ttl = await redis.ttl(key) 32 return { 33 'allowed': False, 34 'retry_after': ttl, 35 'current': current, 36 'max': limit['max'] 37 } 38 39 # Increment counter with expiration 40 pipeline = redis.pipeline() 41 pipeline.incr(key) 42 pipeline.expire(key, limit['window']) 43 await pipeline.execute() 44 45 return {'allowed': True, 'current': current + 1, 'max': limit['max']} 46 47 # Dynamic rate limiting based on risk 48 async def get_dynamic_limit(self, limit_type: str, risk_score: float): 49 base_limit = self.limits[limit_type].copy() 50 if risk_score > 0.8: 51 base_limit['max'] = int(base_limit['max'] * 0.2) 52 elif risk_score > 0.6: 53 base_limit['max'] = int(base_limit['max'] * 0.5) 54 return base_limit 55 56 # Rate limiting decorator 57 def rate_limit(limit_type: str): 58 def decorator(func): 59 async def wrapper(*args, **kwargs): 60 request = kwargs.get('request') or args[0] 61 limiter = SecurityRateLimiter() 62 client_ip = request.client.host 63 user_id = getattr(request.session, 'user_id', None) 64 65 # Check IP-based limits 66 ip_limit = await limiter.check_limit(limit_type, client_ip) 67 if not ip_limit['allowed']: 68 raise HTTPException( 69 status_code=429, 70 detail={ 71 'error': 'Too many requests', 72 'retry_after': ip_limit['retry_after'] 73 } 74 ) 75 76 # Check user-based limits if authenticated 77 if user_id: 78 user_limit = await limiter.check_limit(f'user_{limit_type}', user_id) 79 if not user_limit['allowed']: 80 raise HTTPException( 81 status_code=429, 82 detail={ 83 'error': 'Too many attempts', 84 'retry_after': user_limit['retry_after'] 85 } 86 ) 87 88 return await func(*args, **kwargs) 89 return wrapper 90 return decorator ``` * Go Advanced rate limiting ```go 1 import ( 2 "context" 3 "fmt" 4 "time" 5 ) 6 7 type RateLimit struct { 8 Window time.Duration 9 Max int 10 } 11 12 type SecurityRateLimiter struct { 13 limits map[string]RateLimit 14 redis RedisClient 15 } 16 17 func NewSecurityRateLimiter(redis RedisClient) *SecurityRateLimiter { 18 return &SecurityRateLimiter{ 19 redis: redis, 20 limits: map[string]RateLimit{ 21 // Per-IP limits 22 "login_attempts": {Window: 15 * time.Minute, Max: 10}, 23 "token_requests": {Window: time.Hour, Max: 100}, 24 25 // Per-user limits 26 "user_login_attempts": {Window: time.Hour, Max: 5}, 27 "user_token_refresh": {Window: time.Hour, Max: 50}, 28 29 // Global limits 30 "total_requests": {Window: time.Minute, Max: 10000}, 31 }, 32 } 33 } 34 35 type LimitResult struct { 36 Allowed bool 37 RetryAfter int64 38 Current int 39 Max int 40 } 41 42 func (rl *SecurityRateLimiter) CheckLimit(ctx context.Context, limitType, identifier string, customLimit *RateLimit) (*LimitResult, error) { 43 limit := customLimit 44 if limit == nil { 45 l, exists := rl.limits[limitType] 46 if !exists { 47 return &LimitResult{Allowed: true}, nil 48 } 49 limit = &l 50 } 51 52 key := fmt.Sprintf("%s:%s", limitType, identifier) 53 current, err := rl.redis.Get(ctx, key).Int() 54 if err != nil && err != redis.Nil { 55 return nil, err 56 } 57 58 if current >= limit.Max { 59 ttl, _ := rl.redis.TTL(ctx, key).Result() 60 await rl.logRateLimitExceeded(limitType, identifier, current) 61 return &LimitResult{ 62 Allowed: false, 63 RetryAfter: int64(ttl.Seconds()), 64 Current: current, 65 Max: limit.Max, 66 }, nil 67 } 68 69 // Increment counter with expiration 70 pipe := rl.redis.Pipeline() 71 pipe.Incr(ctx, key) 72 pipe.Expire(ctx, key, limit.Window) 73 _, err = pipe.Exec(ctx) 74 if err != nil { 75 return nil, err 76 } 77 78 return &LimitResult{ 79 Allowed: true, 80 Current: current + 1, 81 Max: limit.Max, 82 }, nil 83 } 84 85 // Dynamic rate limiting based on risk 86 func (rl *SecurityRateLimiter) GetDynamicLimit(limitType string, riskScore float64) *RateLimit { 87 baseLimit, exists := rl.limits[limitType] 88 if !exists { 89 return nil 90 } 91 92 if riskScore > 0.8 { 93 return &RateLimit{ 94 Window: baseLimit.Window, 95 Max: int(float64(baseLimit.Max) * 0.2), 96 } 97 } else if riskScore > 0.6 { 98 return &RateLimit{ 99 Window: baseLimit.Window, 100 Max: int(float64(baseLimit.Max) * 0.5), 101 } 102 } 103 104 return &baseLimit 105 } 106 107 // Rate limiting middleware 108 func (rl *SecurityRateLimiter) RateLimitMiddleware(limitType string) gin.HandlerFunc { 109 return func(c *gin.Context) { 110 clientIP := c.ClientIP() 111 userID, _ := c.Get("userID") 112 113 // Check IP-based limits 114 ipLimit, err := rl.CheckLimit(c.Request.Context(), limitType, clientIP, nil) 115 if err != nil { 116 c.JSON(500, gin.H{"error": "Internal server error"}) 117 c.Abort() 118 return 119 } 120 121 if !ipLimit.Allowed { 122 c.JSON(429, gin.H{ 123 "error": "Too many requests", 124 "retry_after": ipLimit.RetryAfter, 125 }) 126 c.Abort() 127 return 128 } 129 130 // Check user-based limits if authenticated 131 if userID != nil { 132 userLimit, err := rl.CheckLimit(c.Request.Context(), "user_"+limitType, userID.(string), nil) 133 if err != nil { 134 c.JSON(500, gin.H{"error": "Internal server error"}) 135 c.Abort() 136 return 137 } 138 139 if !userLimit.Allowed { 140 c.JSON(429, gin.H{ 141 "error": "Too many attempts", 142 "retry_after": userLimit.RetryAfter, 143 }) 144 c.Abort() 145 return 146 } 147 } 148 149 c.Next() 150 } 151 } ``` * Java Advanced rate limiting ```java 1 import java.time.Duration; 2 import java.time.Instant; 3 import java.util.Map; 4 import java.util.HashMap; 5 import java.util.concurrent.CompletableFuture; 6 7 public class RateLimit { 8 private final Duration window; 9 private final int max; 10 11 // constructors, getters... 12 } 13 14 @Component 15 public class SecurityRateLimiter { 16 private final Map limits; 17 private final RedisTemplate redisTemplate; 18 19 public SecurityRateLimiter(RedisTemplate redisTemplate) { 20 this.redisTemplate = redisTemplate; 21 this.limits = Map.of( 22 // Per-IP limits 23 "login_attempts", new RateLimit(Duration.ofMinutes(15), 10), 24 "token_requests", new RateLimit(Duration.ofHours(1), 100), 25 26 // Per-user limits 27 "user_login_attempts", new RateLimit(Duration.ofHours(1), 5), 28 "user_token_refresh", new RateLimit(Duration.ofHours(1), 50), 29 30 // Global limits 31 "total_requests", new RateLimit(Duration.ofMinutes(1), 10000) 32 ); 33 } 34 35 public static class LimitResult { 36 private final boolean allowed; 37 private final long retryAfter; 38 private final int current; 39 private final int max; 40 41 // constructors, getters... 42 } 43 44 public CompletableFuture checkLimit(String limitType, String identifier, RateLimit customLimit) { 45 return CompletableFuture.supplyAsync(() -> { 46 RateLimit limit = customLimit != null ? customLimit : limits.get(limitType); 47 if (limit == null) { 48 return new LimitResult(true, 0, 0, 0); 49 } 50 51 String key = limitType + ":" + identifier; 52 String currentStr = redisTemplate.opsForValue().get(key); 53 int current = currentStr != null ? Integer.parseInt(currentStr) : 0; 54 55 if (current >= limit.getMax()) { 56 Long ttl = redisTemplate.getExpire(key); 57 logRateLimitExceeded(limitType, identifier, current); 58 return new LimitResult(false, ttl, current, limit.getMax()); 59 } 60 61 // Increment counter with expiration 62 redisTemplate.opsForValue().increment(key); 63 redisTemplate.expire(key, limit.getWindow()); 64 65 return new LimitResult(true, 0, current + 1, limit.getMax()); 66 }); 67 } 68 69 // Dynamic rate limiting based on risk 70 public RateLimit getDynamicLimit(String limitType, double riskScore) { 71 RateLimit baseLimit = limits.get(limitType); 72 if (baseLimit == null) return null; 73 74 if (riskScore > 0.8) { 75 return new RateLimit(baseLimit.getWindow(), (int) (baseLimit.getMax() * 0.2)); 76 } else if (riskScore > 0.6) { 77 return new RateLimit(baseLimit.getWindow(), (int) (baseLimit.getMax() * 0.5)); 78 } 79 80 return baseLimit; 81 } 82 } 83 84 // Rate limiting interceptor 85 @Component 86 public class RateLimitInterceptor implements HandlerInterceptor { 87 88 private final SecurityRateLimiter rateLimiter; 89 90 public RateLimitInterceptor(SecurityRateLimiter rateLimiter) { 91 this.rateLimiter = rateLimiter; 92 } 93 94 @Override 95 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 96 Object handler) throws Exception { 97 String clientIP = getClientIP(request); 98 String userID = getUserID(request); 99 100 // Check IP-based limits 101 LimitResult ipLimit = rateLimiter.checkLimit("login_attempts", clientIP, null).get(); 102 if (!ipLimit.isAllowed()) { 103 response.setStatus(429); 104 response.getWriter().write(String.format( 105 "{\"error\":\"Too many requests\",\"retry_after\":%d}", 106 ipLimit.getRetryAfter() 107 )); 108 return false; 109 } 110 111 // Check user-based limits if authenticated 112 if (userID != null) { 113 LimitResult userLimit = rateLimiter.checkLimit("user_login_attempts", userID, null).get(); 114 if (!userLimit.isAllowed()) { 115 response.setStatus(429); 116 response.getWriter().write(String.format( 117 "{\"error\":\"Too many attempts\",\"retry_after\":%d}", 118 userLimit.getRetryAfter() 119 )); 120 return false; 121 } 122 } 123 124 return true; 125 } 126 127 private String getClientIP(HttpServletRequest request) { 128 String xForwardedFor = request.getHeader("X-Forwarded-For"); 129 if (xForwardedFor != null && !xForwardedFor.isEmpty()) { 130 return xForwardedFor.split(",")[0].trim(); 131 } 132 return request.getRemoteAddr(); 133 } 134 135 private String getUserID(HttpServletRequest request) { 136 HttpSession session = request.getSession(false); 137 return session != null ? (String) session.getAttribute("userID") : null; 138 } 139 } ``` ## Production security checklist [Section titled “Production security checklist”](#production-security-checklist) ### Pre-deployment validation [Section titled “Pre-deployment validation”](#pre-deployment-validation) 1. **Environment security** * \[ ] All secrets stored in secure environment variables * \[ ] HTTPS enforced in production (no mixed content) * \[ ] Security headers configured (HSTS, CSP, X-Frame-Options) * \[ ] Database connections encrypted 2. **Authentication configuration** * \[ ] Redirect URIs validated and restricted * \[ ] Token lifetimes appropriate for security requirements * \[ ] Refresh token rotation enabled * \[ ] State parameter validation implemented 3. **Session management** * \[ ] Secure session storage configured * \[ ] Session timeout policies defined * \[ ] Concurrent session limits set * \[ ] Session invalidation on logout 4. **Rate limiting and monitoring** * \[ ] Rate limiting configured for all auth endpoints * \[ ] Security event logging implemented * \[ ] Anomaly detection systems deployed * \[ ] Alert systems configured ### Security testing procedures [Section titled “Security testing procedures”](#security-testing-procedures) Test security measures before production deployment: Security testing commands ```bash 1 # OWASP ZAP security scan 2 zap-cli quick-scan --self-contained \ 3 --start-options '-config api.disablekey=true' \ 4 https://your-app.com 5 6 # SSL/TLS configuration test 7 testssl --full https://your-app.com 8 9 # CSRF protection test 10 curl -X POST https://your-app.com/auth/login \ 11 -H "Content-Type: application/json" \ 12 -d '{"email":"test@example.com"}' 13 14 # Rate limiting test 15 for i in {1..20}; do 16 curl -X POST https://your-app.com/auth/login \ 17 -H "Content-Type: application/json" \ 18 -d '{"email":"test@example.com","password":"wrong"}' 19 done ``` ### Incident response procedures [Section titled “Incident response procedures”](#incident-response-procedures) Define procedures for handling security incidents: 1. **Detection** - Automated alerts for suspicious activities 2. **Assessment** - Rapid impact evaluation and threat classification 3. **Containment** - Immediate actions to limit damage 4. **Investigation** - Forensic analysis and root cause identification 5. **Recovery** - System restoration and security improvements 6. **Communication** - Stakeholder notifications and compliance reporting Security is an ongoing process Security implementation continues after deployment. Review and update security measures regularly, monitor for new threats, and maintain incident response capabilities. ### Production requirements [Section titled “Production requirements”](#production-requirements) * **Use HTTPS** - Required in production for secure token transmission * **Store tokens securely** - Use HTTP-only cookies or secure server-side storage * **Validate redirects** - Configure allowed redirect URIs in your dashboard This guide provides the foundation for implementing robust authentication security. Combine these patterns with regular security assessments and stay updated on emerging threats. --- # DOCUMENT BOUNDARY --- # Pre-check SSO by domain > Validate that a user's email domain has an active SSO connection before redirecting to prevent dead-end redirects and improve user experience. When using discovery through `loginHint`, validate that the user’s email domain has an active SSO connection before redirecting. This prevents dead-end redirects and improves user experience by routing users to the correct authentication path. ## When to use domain pre-checking [Section titled “When to use domain pre-checking”](#when-to-use-domain-pre-checking) Use domain pre-checking when: * You implement identifier-driven or SSO button flows that collect email first * You infer SSO availability from the user’s email domain * You want to show helpful error messages for domains without SSO Skip this check when: * You already pass `organizationId` explicitly (you know the organization) * You implement organization-specific pages where SSO is always available ## Implementation workflow [Section titled “Implementation workflow”](#implementation-workflow) 1. ## Capture the user’s email and extract the domain [Section titled “Capture the user’s email and extract the domain”](#capture-the-users-email-and-extract-the-domain) First, collect the user’s email address through your login form. Login form handler ```javascript 1 // Extract domain from user's email 2 const email = req.body.email; 3 const domain = email.split('@')[1]; // e.g., "acmecorp.com" ``` 2. ## Query for SSO connections by domain [Section titled “Query for SSO connections by domain”](#query-for-sso-connections-by-domain) Use the Scalekit API to check if the domain has an active SSO connection configured. * Node.js Express.js ```javascript 1 // Use case: Check if user's domain has SSO before redirecting 2 app.post('/auth/check-sso', async (req, res) => { 3 const { email } = req.body; 4 const domain = email.split('@')[1]; 5 6 try { 7 // Query Scalekit for connections matching this domain 8 const connections = await scalekit.connection.listConnections({ 9 domain: domain 10 }); 11 12 if (connections.length > 0) { 13 // Domain has active SSO - redirect to SSO login 14 const authorizationURL = scalekit.getAuthorizationUrl( 15 process.env.REDIRECT_URI, 16 { loginHint: email } 17 ); 18 res.json({ ssoAvailable: true, redirectUrl: authorizationURL }); 19 } else { 20 // No SSO configured - route to password or social login 21 res.json({ ssoAvailable: false, message: 'Please use password login' }); 22 } 23 } catch (error) { 24 console.error('Failed to check SSO availability:', error); 25 res.status(500).json({ error: 'sso_check_failed' }); 26 } 27 }); ``` * Python Flask ```python 1 # Use case: Check if user's domain has SSO before redirecting 2 @app.route('/auth/check-sso', methods=['POST']) 3 def check_sso(): 4 data = request.get_json() 5 email = data.get('email') 6 domain = email.split('@')[1] 7 8 try: 9 # Query Scalekit for connections matching this domain 10 connections = scalekit_client.connection.list_connections( 11 domain=domain 12 ) 13 14 if len(connections) > 0: 15 # Domain has active SSO - redirect to SSO login 16 options = AuthorizationUrlOptions() 17 options.login_hint = email 18 authorization_url = scalekit_client.get_authorization_url( 19 redirect_uri=os.getenv("REDIRECT_URI"), 20 options=options 21 ) 22 return jsonify({ 23 'ssoAvailable': True, 24 'redirectUrl': authorization_url 25 }) 26 else: 27 # No SSO configured - route to password or social login 28 return jsonify({ 29 'ssoAvailable': False, 30 'message': 'Please use password login' 31 }) 32 except Exception as error: 33 print(f"Failed to check SSO availability: {error}") 34 return jsonify({'error': 'sso_check_failed'}), 500 ``` * Go Gin ```go 1 // Use case: Check if user's domain has SSO before redirecting 2 func checkSSOHandler(c *gin.Context) { 3 var body struct { 4 Email string `json:"email"` 5 } 6 c.BindJSON(&body) 7 8 domain := strings.Split(body.Email, "@")[1] 9 10 // Query Scalekit for connections matching this domain 11 connections, err := scalekitClient.Connection.ListConnections( 12 &scalekit.ListConnectionsOptions{ 13 Domain: domain, 14 }, 15 ) 16 17 if err != nil { 18 log.Printf("Failed to check SSO availability: %v", err) 19 c.JSON(http.StatusInternalServerError, gin.H{"error": "sso_check_failed"}) 20 return 21 } 22 23 if len(connections) > 0 { 24 // Domain has active SSO - redirect to SSO login 25 authorizationURL, _ := scalekitClient.GetAuthorizationUrl( 26 os.Getenv("REDIRECT_URI"), 27 scalekit.AuthorizationUrlOptions{ 28 LoginHint: body.Email, 29 }, 30 ) 31 c.JSON(http.StatusOK, gin.H{ 32 "ssoAvailable": true, 33 "redirectUrl": authorizationURL, 34 }) 35 } else { 36 // No SSO configured - route to password or social login 37 c.JSON(http.StatusOK, gin.H{ 38 "ssoAvailable": false, 39 "message": "Please use password login", 40 }) 41 } 42 } ``` * Java Spring Boot ```java 1 // Use case: Check if user's domain has SSO before redirecting 2 @PostMapping(path = "/auth/check-sso") 3 public ResponseEntity> checkSSOHandler(@RequestBody CheckSSORequest body) { 4 String email = body.getEmail(); 5 String domain = email.split("@")[1]; 6 7 try { 8 // Query Scalekit for connections matching this domain 9 ListConnectionsResponse connections = scalekitClient 10 .connection() 11 .listConnections( 12 new ListConnectionsOptions().setDomain(domain) 13 ); 14 15 if (!connections.getConnections().isEmpty()) { 16 // Domain has active SSO - redirect to SSO login 17 String authorizationURL = scalekitClient 18 .authentication() 19 .getAuthorizationUrl( 20 System.getenv("REDIRECT_URI"), 21 new AuthorizationUrlOptions().setLoginHint(email) 22 ) 23 .toString(); 24 25 Map response = new HashMap<>(); 26 response.put("ssoAvailable", true); 27 response.put("redirectUrl", authorizationURL); 28 return ResponseEntity.ok(response); 29 } else { 30 // No SSO configured - route to password or social login 31 Map response = new HashMap<>(); 32 response.put("ssoAvailable", false); 33 response.put("message", "Please use password login"); 34 return ResponseEntity.ok(response); 35 } 36 } catch (Exception error) { 37 System.err.println("Failed to check SSO availability: " + error.getMessage()); 38 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) 39 .body(Collections.singletonMap("error", "sso_check_failed")); 40 } 41 } ``` 3. ## Route users based on SSO availability [Section titled “Route users based on SSO availability”](#route-users-based-on-sso-availability) Based on the API response, either redirect to SSO or show alternative authentication options. Client-side routing ```javascript 1 // Handle the response from your backend 2 const response = await fetch('/auth/check-sso', { 3 method: 'POST', 4 headers: { 'Content-Type': 'application/json' }, 5 body: JSON.stringify({ email: userEmail }) 6 }); 7 8 const data = await response.json(); 9 10 if (data.ssoAvailable) { 11 // Redirect to SSO login 12 window.location.href = data.redirectUrl; 13 } else { 14 // Show password login or social authentication options 15 showPasswordLoginForm(); 16 } ``` --- # DOCUMENT BOUNDARY --- # Link to billing, CRM & HR systems > Production-ready patterns for linking Scalekit organizations and users to Stripe, Salesforce, Workday and other enterprise systems using external identifiers External identifiers enable seamless integration between Scalekit and your existing business systems. This guide provides practical patterns for implementing these integrations across common enterprise scenarios including billing platforms, CRM systems, HR systems, and multi-system workflows. ## Integration patterns overview [Section titled “Integration patterns overview”](#integration-patterns-overview) External IDs serve as the bridge between Scalekit’s authentication system and your business infrastructure. Common integration scenarios include: * **Billing and subscription management** - Link customers to payment platforms like Stripe, Chargebee * **Customer relationship management** - Sync with Salesforce, HubSpot, Pipedrive * **Human resources systems** - Connect with Workday, BambooHR, ADP * **Internal tools and databases** - Maintain consistency across custom applications * **Multi-system orchestration** - Coordinate data across multiple platforms ## Billing system integration [Section titled “Billing system integration”](#billing-system-integration) Connect organizations and users with your billing platform to track subscriptions, handle payment events, and maintain customer lifecycle data. ### Stripe integration example [Section titled “Stripe integration example”](#stripe-integration-example) This example shows how to handle subscription updates by finding organizations using external IDs and updating their metadata accordingly. * Node.js Stripe webhook handler ```javascript 1 // When a customer subscribes via Stripe 2 app.post('/stripe/webhook', async (req, res) => { 3 const event = req.body; 4 5 if (event.type === 'customer.subscription.updated') { 6 const customerId = event.data.object.customer; 7 8 // Find organization by external ID (Stripe customer ID) 9 const { organization: org } = await scalekit.organization.getOrganizationByExternalId(customerId); 10 11 if (org) { 12 // Update subscription metadata 13 await scalekit.organization.updateOrganization(org.id, { 14 metadata: { 15 ...org.metadata, 16 subscription_status: event.data.object.status, 17 plan_type: event.data.object.items.data[0].price.lookup_key, 18 last_billing_update: new Date().toISOString(), 19 subscription_current_period_end: new Date(event.data.object.current_period_end * 1000).toISOString() 20 } 21 }); 22 23 // Use case: Automatically provision/deprovision features based on subscription status 24 if (event.data.object.status === 'active') { 25 await enablePremiumFeatures(org.id); 26 } else if (event.data.object.status === 'canceled') { 27 await disablePremiumFeatures(org.id); 28 } 29 } 30 } 31 32 // Handle customer deletion 33 if (event.type === 'customer.deleted') { 34 const customerId = event.data.object.id; 35 const { organization: org } = await scalekit.organization.getOrganizationByExternalId(customerId); 36 37 if (org) { 38 await scalekit.organization.updateOrganization(org.id, { 39 metadata: { 40 ...org.metadata, 41 billing_status: 'deleted', 42 deletion_date: new Date().toISOString() 43 } 44 }); 45 } 46 } 47 48 res.status(200).send('OK'); 49 }); ``` * Python Stripe webhook handler ```python 1 # When a customer subscribes via Stripe 2 @app.route('/stripe/webhook', methods=['POST']) 3 def stripe_webhook(): 4 event = request.json 5 6 if event['type'] == 'customer.subscription.updated': 7 customer_id = event['data']['object']['customer'] 8 9 # Find organization by external ID (Stripe customer ID) 10 response = scalekit_client.organization.get_organization_by_external_id(customer_id) 11 org = response[0].organization 12 13 if org: 14 # Update subscription metadata 15 updated_metadata = { 16 **org.metadata, 17 'subscription_status': event['data']['object']['status'], 18 'plan_type': event['data']['object']['items']['data'][0]['price']['lookup_key'], 19 'last_billing_update': datetime.utcnow().isoformat(), 20 'subscription_current_period_end': datetime.fromtimestamp( 21 event['data']['object']['current_period_end'] 22 ).isoformat() 23 } 24 25 update_organization = UpdateOrganization(metadata=updated_metadata) 26 scalekit_client.organization.update_organization( 27 organization_id=org.id, organization=update_organization 28 ) 29 30 # Use case: Automatically provision/deprovision features based on subscription status 31 if event['data']['object']['status'] == 'active': 32 enable_premium_features(org.id) 33 elif event['data']['object']['status'] == 'canceled': 34 disable_premium_features(org.id) 35 36 # Handle customer deletion 37 elif event['type'] == 'customer.deleted': 38 customer_id = event['data']['object']['id'] 39 response = scalekit_client.organization.get_organization_by_external_id(customer_id) 40 org = response[0].organization 41 42 if org: 43 updated_metadata = { 44 **org.metadata, 45 'billing_status': 'deleted', 46 'deletion_date': datetime.utcnow().isoformat() 47 } 48 update_organization = UpdateOrganization(metadata=updated_metadata) 49 scalekit_client.organization.update_organization( 50 organization_id=org.id, organization=update_organization 51 ) 52 53 return 'OK', 200 ``` ### Best practices for billing integration [Section titled “Best practices for billing integration”](#best-practices-for-billing-integration) * **Use Stripe customer IDs as external IDs** for organizations to enable quick lookups during webhook processing * **Store subscription metadata** in organization records for immediate access in your application * **Handle subscription lifecycle events** (trial start, subscription active, canceled, past due) * **Implement idempotency** in webhook handlers to prevent duplicate processing * **Use external IDs for user-level billing** when implementing per-seat pricing models ## CRM synchronization [Section titled “CRM synchronization”](#crm-synchronization) Keep organization and user data synchronized between Scalekit and your CRM system to maintain consistent customer records and enable sales team workflows. ### Salesforce integration example [Section titled “Salesforce integration example”](#salesforce-integration-example) * Node.js Salesforce sync integration ```javascript 1 // Sync organization data with Salesforce 2 async function syncOrganizationWithCRM(organizationId, salesforceAccountId) { 3 try { 4 // Fetch account data from Salesforce 5 const crmData = await salesforce.getAccount(salesforceAccountId); 6 7 // Update Scalekit organization with CRM data 8 await scalekit.organization.updateOrganization(organizationId, { 9 metadata: { 10 salesforce_account_id: salesforceAccountId, 11 industry: crmData.Industry, 12 annual_revenue: crmData.AnnualRevenue, 13 account_owner: crmData.Owner.Name, 14 account_type: crmData.Type, 15 company_size: crmData.NumberOfEmployees, 16 last_crm_sync: new Date().toISOString(), 17 crm_last_modified: crmData.LastModifiedDate 18 } 19 }); 20 21 // Use case: Update user permissions based on account type 22 if (crmData.Type === 'Enterprise') { 23 await enableEnterpriseFeatures(organizationId); 24 } 25 26 } catch (error) { 27 console.error('CRM sync failed:', error); 28 // Log sync failure for monitoring 29 await logSyncFailure('salesforce', organizationId, error); 30 } 31 } 32 33 // Sync user data with Salesforce contacts 34 async function syncUserWithCRM(userId, organizationId, salesforceContactId) { 35 try { 36 const contactData = await salesforce.getContact(salesforceContactId); 37 38 await scalekit.user.updateUser(userId, { 39 metadata: { 40 salesforce_contact_id: salesforceContactId, 41 job_title: contactData.Title, 42 department: contactData.Department, 43 territory: contactData.Sales_Territory__c, 44 last_crm_contact_sync: new Date().toISOString() 45 } 46 }); 47 48 } catch (error) { 49 console.error('User CRM sync failed:', error); 50 } 51 } 52 53 // Bidirectional sync: Update Salesforce when Scalekit data changes 54 async function updateCRMFromScalekit(organizationId) { 55 const { organization: org } = await scalekit.organization.getOrganization(organizationId); 56 57 if (org.metadata.salesforce_account_id) { 58 await salesforce.updateAccount(org.metadata.salesforce_account_id, { 59 Last_Login_Date__c: new Date().toISOString(), 60 Active_Users__c: await getUserCount(organizationId), 61 Subscription_Status__c: org.metadata.plan_type 62 }); 63 } 64 } ``` * Python Salesforce sync integration ```python 1 # Sync organization data with Salesforce 2 async def sync_organization_with_crm(organization_id, salesforce_account_id): 3 try: 4 # Fetch account data from Salesforce 5 crm_data = await salesforce.get_account(salesforce_account_id) 6 7 # Update Scalekit organization with CRM data 8 metadata = { 9 'salesforce_account_id': salesforce_account_id, 10 'industry': crm_data.get('Industry'), 11 'annual_revenue': crm_data.get('AnnualRevenue'), 12 'account_owner': crm_data.get('Owner', {}).get('Name'), 13 'account_type': crm_data.get('Type'), 14 'company_size': crm_data.get('NumberOfEmployees'), 15 'last_crm_sync': datetime.utcnow().isoformat(), 16 'crm_last_modified': crm_data.get('LastModifiedDate') 17 } 18 19 update_organization = UpdateOrganization(metadata=metadata) 20 scalekit_client.organization.update_organization( 21 organization_id=organization_id, organization=update_organization 22 ) 23 24 # Use case: Update user permissions based on account type 25 if crm_data.get('Type') == 'Enterprise': 26 await enable_enterprise_features(organization_id) 27 28 except Exception as error: 29 print(f'CRM sync failed: {error}') 30 # Log sync failure for monitoring 31 await log_sync_failure('salesforce', organization_id, str(error)) 32 33 # Sync user data with Salesforce contacts 34 async def sync_user_with_crm(user_id, organization_id, salesforce_contact_id): 35 try: 36 contact_data = await salesforce.get_contact(salesforce_contact_id) 37 38 metadata = { 39 'salesforce_contact_id': salesforce_contact_id, 40 'job_title': contact_data.get('Title'), 41 'department': contact_data.get('Department'), 42 'territory': contact_data.get('Sales_Territory__c'), 43 'last_crm_contact_sync': datetime.utcnow().isoformat() 44 } 45 46 scalekit.user.update_user(user_id, {'metadata': metadata}) 47 48 except Exception as error: 49 print(f'User CRM sync failed: {error}') 50 51 # Bidirectional sync: Update Salesforce when Scalekit data changes 52 async def update_crm_from_scalekit(organization_id): 53 response = scalekit_client.organization.get_organization(organization_id) 54 org = response[0].organization 55 56 if org.metadata.get('salesforce_account_id'): 57 await salesforce.update_account(org.metadata['salesforce_account_id'], { 58 'Last_Login_Date__c': datetime.utcnow().isoformat(), 59 'Active_Users__c': await get_user_count(organization_id), 60 'Subscription_Status__c': org.metadata.get('plan_type') 61 }) ``` ### CRM integration best practices [Section titled “CRM integration best practices”](#crm-integration-best-practices) * **Use CRM record IDs as external IDs** to enable quick bidirectional lookups * **Implement scheduled sync jobs** to keep data fresh without overloading APIs * **Handle API rate limits** with exponential backoff and queuing * **Store sync timestamps** to enable incremental updates * **Log sync failures** for monitoring and debugging * **Implement conflict resolution** for bidirectional sync scenarios ## HR system integration [Section titled “HR system integration”](#hr-system-integration) Connect user records with HR systems to automate provisioning, maintain employee data, and handle organizational changes. ### Workday integration pattern [Section titled “Workday integration pattern”](#workday-integration-pattern) HR system integration example ```javascript 1 // Sync user data with HR system during onboarding 2 async function syncNewEmployeeWithScalekit(employeeData) { 3 const { employee_id, email, first_name, last_name, department, start_date, manager_email } = employeeData; 4 5 // Find organization by domain or external ID 6 const domain = email.split('@')[1]; 7 const organization = await scalekit.organization.getByDomain(domain); 8 9 if (organization) { 10 // Create user with HR system external ID 11 const { user } = await scalekit.user.createUserAndMembership(organization.id, { 12 email: email, 13 externalId: employee_id, // HR system employee ID 14 metadata: { 15 hr_employee_id: employee_id, 16 department: department, 17 start_date: start_date, 18 manager_email: manager_email, 19 employee_status: 'active', 20 hr_last_sync: new Date().toISOString() 21 }, 22 userProfile: { 23 firstName: first_name, 24 lastName: last_name 25 }, 26 sendInvitationEmail: true 27 }); 28 29 // Use case: Assign department-based roles 30 await assignDepartmentRoles(user.id, department); 31 32 return user; 33 } 34 } 35 36 // Handle employee status changes 37 async function handleEmployeeStatusChange(employee_id, status) { 38 try { 39 // Find user by HR system external ID 40 const { user } = await scalekit.user.getUserByExternalId(employee_id); 41 42 if (user) { 43 if (status === 'terminated') { 44 // Disable user access 45 await scalekit.user.updateUser(user.id, { 46 metadata: { 47 ...user.metadata, 48 employee_status: 'terminated', 49 termination_date: new Date().toISOString() 50 } 51 }); 52 53 // Remove from organization 54 await scalekit.user.deleteMembership(organization.id, user.id); 55 56 } else if (status === 'on_leave') { 57 // Temporarily suspend access 58 await scalekit.user.updateUser(user.id, { 59 metadata: { 60 ...user.metadata, 61 employee_status: 'on_leave', 62 leave_start_date: new Date().toISOString() 63 } 64 }); 65 } 66 } 67 } catch (error) { 68 console.error('HR status sync failed:', error); 69 } 70 } ``` ## Multi-system integration workflows [Section titled “Multi-system integration workflows”](#multi-system-integration-workflows) Orchestrate data across multiple systems using external IDs as the common identifier thread. ### Customer lifecycle automation [Section titled “Customer lifecycle automation”](#customer-lifecycle-automation) Multi-system workflow example ```javascript 1 // Complete customer onboarding workflow 2 async function onboardNewCustomer(customerData) { 3 const { company_name, admin_email, plan_type, salesforce_account_id, stripe_customer_id } = customerData; 4 5 try { 6 // 1. Create organization in Scalekit 7 const { organization } = await scalekit.organization.createOrganization(company_name, { 8 externalId: stripe_customer_id, // Use billing system ID as primary external ID 9 }); 10 11 // The Node.js SDK does not accept metadata at creation, so set it with a follow-up update 12 await scalekit.organization.updateOrganization(organization.id, { 13 metadata: { 14 plan_type: plan_type, 15 salesforce_account_id: salesforce_account_id, 16 stripe_customer_id: stripe_customer_id, 17 onboarding_status: 'pending', 18 created_date: new Date().toISOString() 19 } 20 }); 21 22 // 2. Create admin user 23 const { user } = await scalekit.user.createUserAndMembership(organization.id, { 24 email: admin_email, 25 externalId: `${stripe_customer_id}_admin`, // Composite external ID 26 metadata: { 27 role_type: 'admin', 28 onboarding_step: 'account_created' 29 }, 30 sendInvitationEmail: true 31 }); 32 33 // 3. Update CRM with Scalekit IDs 34 await salesforce.updateAccount(salesforce_account_id, { 35 Scalekit_Organization_ID__c: organization.id, 36 Scalekit_Admin_User_ID__c: user.id, 37 Onboarding_Status__c: 'In Progress' 38 }); 39 40 // 4. Configure billing in Stripe 41 await stripe.customers.update(stripe_customer_id, { 42 metadata: { 43 scalekit_org_id: organization.id, 44 scalekit_admin_user_id: user.id 45 } 46 }); 47 48 // 5. Send onboarding notifications 49 await sendOnboardingEmail(admin_email, organization.id); 50 await notifySalesTeam(salesforce_account_id, 'customer_onboarded'); 51 52 return { organization, user }; 53 54 } catch (error) { 55 console.error('Customer onboarding failed:', error); 56 // Rollback logic here 57 throw error; 58 } 59 } ``` ## Error handling and retry patterns [Section titled “Error handling and retry patterns”](#error-handling-and-retry-patterns) Implement robust error handling for external system integrations to ensure data consistency and reliability. ### Retry with exponential backoff [Section titled “Retry with exponential backoff”](#retry-with-exponential-backoff) Robust integration error handling ```javascript 1 // Utility function for retrying API calls with exponential backoff 2 async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) { 3 for (let attempt = 1; attempt <= maxRetries; attempt++) { 4 try { 5 return await fn(); 6 } catch (error) { 7 if (attempt === maxRetries) { 8 throw error; 9 } 10 11 // Exponential backoff with jitter 12 const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 1000; 13 await new Promise(resolve => setTimeout(resolve, delay)); 14 } 15 } 16 } 17 18 // Resilient external ID lookup 19 async function findOrganizationWithRetry(externalId) { 20 return retryWithBackoff(async () => { 21 const { organization: org } = await scalekit.organization.getOrganizationByExternalId(externalId); 22 if (!org) { 23 throw new Error(`Organization not found for external ID: ${externalId}`); 24 } 25 return org; 26 }); 27 } 28 29 // Webhook processing with error handling 30 app.post('/webhook', async (req, res) => { 31 try { 32 const { external_id, event_type, data } = req.body; 33 34 // Find organization with retry logic 35 const organization = await findOrganizationWithRetry(external_id); 36 37 // Process the webhook data 38 await processWebhookEvent(organization, event_type, data); 39 40 res.status(200).json({ status: 'success' }); 41 42 } catch (error) { 43 console.error('Webhook processing failed:', error); 44 45 // Queue for retry if it's a temporary failure 46 if (isRetryableError(error)) { 47 await queueWebhookForRetry(req.body); 48 res.status(202).json({ status: 'queued_for_retry' }); 49 } else { 50 res.status(400).json({ status: 'error', message: error.message }); 51 } 52 } 53 }); 54 55 function isRetryableError(error) { 56 return error.code === 'NETWORK_ERROR' || 57 error.code === 'RATE_LIMITED' || 58 error.status >= 500; 59 } ``` ## Security considerations [Section titled “Security considerations”](#security-considerations) When implementing external ID integrations, follow these security best practices: ### Webhook security [Section titled “Webhook security”](#webhook-security) Secure webhook handling ```javascript 1 // Verify webhook signatures 2 function verifyWebhookSignature(payload, signature, secret) { 3 const expectedSignature = crypto 4 .createHmac('sha256', secret) 5 .update(payload) 6 .digest('hex'); 7 8 return crypto.timingSafeEqual( 9 Buffer.from(signature, 'hex'), 10 Buffer.from(expectedSignature, 'hex') 11 ); 12 } 13 14 // Rate limiting for webhook endpoints 15 const webhookLimiter = rateLimit({ 16 windowMs: 1 * 60 * 1000, // 1 minute 17 max: 100, // limit each IP to 100 requests per windowMs 18 message: 'Too many webhook requests from this IP' 19 }); 20 21 app.post('/webhook', webhookLimiter, (req, res) => { 22 // Verify signature before processing 23 if (!verifyWebhookSignature(req.body, req.headers['x-signature'], process.env.WEBHOOK_SECRET)) { 24 return res.status(401).json({ error: 'Invalid signature' }); 25 } 26 27 // Process webhook... 28 }); ``` ### Data validation and sanitization [Section titled “Data validation and sanitization”](#data-validation-and-sanitization) * **Validate external IDs** before using them in database queries * **Sanitize metadata** to prevent injection attacks * **Use prepared statements** for database operations * **Implement input validation** for all external data * **Log security events** for monitoring and auditing ## Monitoring and observability [Section titled “Monitoring and observability”](#monitoring-and-observability) Implement comprehensive monitoring for external ID integrations to ensure system health and quick issue resolution. ### Integration health monitoring [Section titled “Integration health monitoring”](#integration-health-monitoring) Integration monitoring example ```javascript 1 // Track integration health metrics 2 class IntegrationMonitor { 3 constructor() { 4 this.metrics = { 5 successful_syncs: 0, 6 failed_syncs: 0, 7 average_sync_time: 0, 8 last_successful_sync: null 9 }; 10 } 11 12 async recordSyncAttempt(system, success, duration) { 13 if (success) { 14 this.metrics.successful_syncs++; 15 this.metrics.last_successful_sync = new Date(); 16 } else { 17 this.metrics.failed_syncs++; 18 } 19 20 // Update average sync time 21 this.updateAverageSyncTime(duration); 22 23 // Send metrics to monitoring system 24 await this.sendMetrics(system, this.metrics); 25 } 26 27 updateAverageSyncTime(duration) { 28 const totalSyncs = this.metrics.successful_syncs + this.metrics.failed_syncs; 29 this.metrics.average_sync_time = 30 (this.metrics.average_sync_time * (totalSyncs - 1) + duration) / totalSyncs; 31 } 32 } 33 34 // Usage in integration functions 35 const monitor = new IntegrationMonitor(); 36 37 async function syncWithExternalSystem(externalId, data) { 38 const startTime = Date.now(); 39 let success = false; 40 41 try { 42 await performSync(externalId, data); 43 success = true; 44 } catch (error) { 45 console.error('Sync failed:', error); 46 throw error; 47 } finally { 48 const duration = Date.now() - startTime; 49 await monitor.recordSyncAttempt('external_system', success, duration); 50 } 51 } ``` ## Best practices summary [Section titled “Best practices summary”](#best-practices-summary) ### External ID management [Section titled “External ID management”](#external-id-management) * **Use meaningful, stable identifiers** from your primary business system * **Implement consistent naming conventions** across all external IDs * **Handle ID migration scenarios** when external systems change * **Validate external IDs** before using them in operations ### Integration reliability [Section titled “Integration reliability”](#integration-reliability) * **Implement retry logic** with exponential backoff for API calls * **Use webhooks for real-time sync** and scheduled jobs for periodic reconciliation * **Handle rate limits** gracefully with queuing and backoff strategies * **Monitor integration health** with comprehensive metrics and alerting ### Security and compliance [Section titled “Security and compliance”](#security-and-compliance) * **Verify webhook signatures** to ensure authenticity * **Implement rate limiting** on webhook endpoints * **Validate and sanitize** all external data * **Audit integration activities** for compliance requirements ### Performance optimization [Section titled “Performance optimization”](#performance-optimization) * **Cache frequently accessed external ID mappings** * **Batch operations** where possible to reduce API calls * **Use appropriate timeouts** for external API calls * **Implement circuit breakers** for unreliable external services This integration approach enables seamless data flow between Scalekit and your business systems while maintaining security, reliability, and performance standards. --- # DOCUMENT BOUNDARY --- # Modular social logins > Learn how to integrate modular social logins module with Scalekit Social login enables authentication through existing accounts from providers like Google, Microsoft, and GitHub. Users don’t need to create or remember new credentials, making the sign-in process faster and more convenient. This guide explains how to implement social login in your application with Scalekit’s OAuth 2.0 integration. ![How Scalekit works](/.netlify/images?url=_astro%2F0.CtcbvoxC.png\&w=5776\&h=1924\&dpl=6aaa70ad2ea7b40008ad2afd) 1. ## Set up Scalekit [Section titled “Set up Scalekit”](#set-up-scalekit) Use the following instructions to install the SDK for your technology stack. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` Follow the [installation guide](/authenticate/set-up-scalekit/) to configure Scalekit in your application. Go to Dashboard > Authentication > General to **turn off the Full-Stack Auth** since you’d use the modular social logins module. This disables user management and session management features and let’s to only use social login authentication. 2. ## Configure social login providers [Section titled “Configure social login providers”](#configure-social-login-providers) Google login is pre-configured in all development environments for simplified testing. You can integrate additional social login providers by setting up your own connection credentials with each provider. Navigate to **Authentication** > **Auth Methods** > **Social logins** in your dashboard to configure these settings ### Google Enable users to sign in with their Google accounts using OAuth 2.0 [Set up →](/guides/integrations/social-connections/google) ### GitHub Allow users to authenticate using their GitHub credentials [Set up →](/guides/integrations/social-connections/github) ### Microsoft Integrate Microsoft accounts for seamless user authentication [Set up →](/guides/integrations/social-connections/microsoft) ### GitLab Enable GitLab-based authentication for your application [Set up →](/guides/integrations/social-connections/gitlab) ### LinkedIn Let users sign in with their LinkedIn accounts using OAuth 2.0 [Set up →](/guides/integrations/social-connections/linkedin) ### Salesforce Enable Salesforce-based authentication for your application [Set up →](/guides/integrations/social-connections/salesforce) After configuration, Scalekit can interact with these providers to authenticate users and verify their identities. 3. ## From your application, redirect users to provider’s OAuth pages [Section titled “From your application, redirect users to provider’s OAuth pages”](#from-your-application-redirect-users-to-providers-oauth-pages) Create an authorization URL to redirect users to social provider’s sign-in page. Use the Scalekit SDK to construct this URL with your redirect URI and provider identifier. Supported `provider` values: `google`, `microsoft`, `github`, `salesforce`, `linkedin`, `gitlab` * Node.js ```javascript 1 // 2 const authorizationURL = scalekit.getAuthorizationUrl(redirectUri, { 3 provider: 'google', 4 state: state, // recommended 5 }); 6 7 /* 8 https://auth.scalekit.com/authorize? 9 client_id=skc_122056050118122349527& 10 redirect_uri=https://yourapp.com/auth/callback& 11 provider=google 12 */ ``` * Python ```python 1 options = AuthorizationUrlOptions() 2 3 options.provider = 'google' 4 5 authorization_url = scalekit_client.get_authorization_url( 6 redirect_uri=, 7 options=options 8 ) ``` * Go ```go 1 options := scalekitClient.AuthorizationUrlOptions{} 2 // Pass the social login provider details while constructing the authorization URL. 3 options.Provider = "google" 4 5 authorizationURL := scalekitClient.GetAuthorizationUrl( 6 redirectUrl, 7 options, 8 ) 9 // Next step is to redirect the user to this authorization URL 10 } ``` * Java ```java 1 package com.scalekit; 2 3 import com.scalekit.internal.http.AuthorizationUrlOptions; 4 5 public class Main { 6 7 public static void main(String[] args) { 8 ScalekitClient scalekitClient = new ScalekitClient( 9 "", 10 "", 11 "" 12 ); 13 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 14 options.setProvider("google"); 15 try { 16 // Pass the social login provider details while constructing the authorization URL. 17 String url = scalekitClient.authentication().getAuthorizationUrl(redirectUrl, options).toString(); 18 } catch (Exception e) { 19 System.out.println(e.getMessage()); 20 } 21 } 22 } ``` After the user successfully authenticates with the selected social login provider, they will be redirected back to your application. Scalekit passes an authorization `code` to your registered callback endpoint, which you’ll use in the next step to retrieve user information. 4. ## Get user details from the callback [Section titled “Get user details from the callback”](#get-user-details-from-the-callback) After successful authentication, Scalekit creates a user record and sends the user information to your callback endpoint. 1. Add a callback endpoint in your application (typically `https://your-app.com/auth/callback`) 2. [Register](/guides/dashboard/allowed-callback-url/) it in your Scalekit dashboard > Authentication > Redirect URLS > Allowed Callback URLs In authentication flow, Scalekit redirects to your callback URL with an authorization code. Your application exchanges this code for the user’s profile information and proceed to creating session and logging in the user. * Node.js ```javascript 1 const { code, state, error, error_description } = req.query; 2 3 if (error) { 4 // Handle errors (use error_description if present) 5 } 6 7 const authResult = await scalekit.authenticateWithCode(code, redirectUri); 8 9 // authResult.user has the authenticated user's details 10 const userEmail = authResult.user.email; 11 12 // Next step: create a session for this user and allow access ``` * Python ```python 1 code = request.args.get('code') 2 error = request.args.get('error') 3 error_description = request.args.get('error_description') 4 5 if error: 6 raise Exception(error_description) 7 8 auth_result = scalekit_client.authenticate_with_code( 9 code, 10 11 ) 12 13 # result.user has the authenticated user's details 14 user_email = auth_result.user.email 15 16 # Next step: create a session for this user and allow access ``` * Go ```go 1 code := r.URL.Query().Get("code") 2 error := r.URL.Query().Get("error") 3 errorDescription := r.URL.Query().Get("error_description") 4 5 if error != "" { 6 // Handle errors and exit 7 } 8 9 authResult, err := scalekitClient.AuthenticateWithCode(r.Context(), code, redirectUrl) 10 if err != nil { 11 // Handle errors and exit 12 } 13 14 // authResult.User has the authenticated user's details 15 userEmail := authResult.User.Email 16 17 // Next step: create a session for this user and allow access ``` * Java ```java 1 String code = request.getParameter("code"); 2 String error = request.getParameter("error"); 3 String errorDescription = request.getParameter("error_description"); 4 if (error != null && !error.isEmpty()) { 5 // Handle errors 6 return; 7 } 8 try { 9 AuthenticationResponse res = scalekitClient.authentication().authenticateWithCode(code, redirectUrl); 10 // res.getIdTokenClaims() has the authenticated user's details 11 String userEmail = res.getIdTokenClaims().getEmail(); 12 13 } catch (Exception e) { 14 // Handle errors 15 } 16 17 // Next step: create a session for this user and allow access ``` The *auth result* object * Auth result ```js { user: { email: "john.doe@example.com" // User's email // any additional common fields }, idToken: "", // JWT with user profile claims accessToken: "", // JWT for API calls expiresIn: 899 // Seconds until expiration } ``` * Decoded ID token (JWT) ```json { "alg": "RS256", "kid": "snk_82937465019283746", "typ": "JWT" }.{ "amr": [ "conn_92847563920187364" ], "at_hash": "j8kqPm3nRt5Kx2Vy9wL_Zp", "aud": [ "skc_73645291837465928" ], "azp": "skc_73645291837465928", "c_hash": "Hy4k2M9pWnX7vqR8_Jt3bg", "client_id": "skc_73645291837465928", "email": "alice.smith@example.com", "email_verified": true, "exp": 1751697469, "iat": 1751438269, "iss": "https://demo-company-dev.scalekit.cloud", "sid": "ses_83746592018273645", "sub": "conn_92847563920187364;alice.smith@example.com" // A scalekit user ID is sent if user management is enabled }.[Signature] ``` * Decoded access token ```json { "alg": "RS256", "kid": "snk_794467716206433", "typ": "JWT" }.{ "iss": "https://acme-corp-dev.scalekit.cloud", "sub": "conn_794467724427269;robert.wilson@acme.com", "aud": [ "skc_794467724259497" ], "exp": 1751439169, "iat": 1751438269, "nbf": 1751438269, "client_id": "skc_794467724259497", "jti": "tkn_794754665320942", // External identifiers if updated on Scalekit "xoid": "ext_org_123", // Organization ID "xuid": "ext_usr_456" // User ID }.[Signature] ``` Your application now supports social login authentication. Users can sign in securely using their preferred social identity providers like Google, GitHub, Microsoft, and more. --- # DOCUMENT BOUNDARY --- # Preserve target route post-auth > Redirect users back to page they asked for after authentication using a signed return URL Users may bookmark specific pages of your app, but their session might be expired. They need to be redirected to the page they asked for after authentication. That means your app needs to preserve the user’s original destination. You will capture the user’s original destination, carry it through the OAuth flow safely, and redirect back after login. You will prevent open-redirect attacks by validating and signing the return URL. 1. ## Capture the intended destination [Section titled “Capture the intended destination”](#capture-the-intended-destination) When an unauthenticated user requests a protected route, capture its path. * Node.js Express.js ```javascript 1 app.get('/login', (req, res) => { 2 const nextPath = typeof req.query.next === 'string' ? req.query.next : '/' 3 // Only allow internal paths 4 const safe = nextPath.startsWith('/') && !nextPath.startsWith('//') ? nextPath : '/' 5 res.cookie('sk_return_to', safe, { httpOnly: true, secure: true, sameSite: 'lax', path: '/' }) 6 // build authorization URL next 7 }) ``` * Python Flask ```python 1 @app.route('/login') 2 def login(): 3 next_path = request.args.get('next', '/') 4 safe = next_path if next_path.startswith('/') and not next_path.startswith('//') else '/' 5 resp = make_response() 6 resp.set_cookie('sk_return_to', safe, httponly=True, secure=True, samesite='Lax', path='/') 7 return resp ``` * Go Gin ```go 1 func login(c *gin.Context) { 2 nextPath := c.Query("next") 3 if nextPath == "" || !strings.HasPrefix(nextPath, "/") || strings.HasPrefix(nextPath, "//") { 4 nextPath = "/" 5 } 6 cookie := &http.Cookie{Name: "sk_return_to", Value: nextPath, HttpOnly: true, Secure: true, Path: "/"} 7 http.SetCookie(c.Writer, cookie) 8 } ``` * Java Spring ```java 1 @GetMapping("/login") 2 public void login(HttpServletRequest request, HttpServletResponse response) { 3 String nextPath = Optional.ofNullable(request.getParameter("next")).orElse("/"); 4 boolean safe = nextPath.startsWith("/") && !nextPath.startsWith("//"); 5 Cookie cookie = new Cookie("sk_return_to", safe ? nextPath : "/"); 6 cookie.setHttpOnly(true); cookie.setSecure(true); cookie.setPath("/"); 7 response.addCookie(cookie); 8 } ``` 2. ## Build the authorization URL [Section titled “Build the authorization URL”](#build-the-authorization-url) Generate the authorization URL as in the quickstart. Optionally include a short hint in `state` like `"n=/billing"` after signing or encoding. * Node.js Express.js ```javascript 1 const redirectUri = 'https://your-app.com/auth/callback' 2 const options = { scopes: ['openid','profile','email','offline_access'] } 3 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options) 4 res.redirect(authorizationUrl) ``` * Python Flask ```python 1 redirect_uri = 'https://your-app.com/auth/callback' 2 options = AuthorizationUrlOptions() 3 options.scopes = ['openid', 'profile', 'email', 'offline_access'] 4 authorization_url = scalekit_client.get_authorization_url(redirect_uri, options) 5 return redirect(authorization_url) ``` * Go Gin ```go 1 redirectUri := "https://your-app.com/auth/callback" 2 options := scalekitClient.AuthorizationUrlOptions{Scopes: []string{"openid","profile","email","offline_access"}} 3 authorizationURL, _ := scalekitClient.GetAuthorizationUrl(redirectUri, options) 4 c.Redirect(http.StatusFound, authorizationURL.String()) ``` * Java Spring ```java 1 String redirectUri = "https://your-app.com/auth/callback"; 2 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 3 options.setScopes(Arrays.asList("openid","profile","email","offline_access")); 4 URL authorizationUrl = scalekitClient.authentication().getAuthorizationUrl(redirectUri, options); 5 return new RedirectView(authorizationUrl.toString()); ``` 3. ## After callback, redirect safely [Section titled “After callback, redirect safely”](#after-callback-redirect-safely) After exchanging the code and creating a session, read `sk_return_to`. Validate and normalize the path. Default to `/dashboard` or `/`. * Node.js Express.js ```javascript 1 app.get('/auth/callback', async (req, res) => { 2 // ... exchange code ... 3 const raw = req.cookies.sk_return_to || '/' 4 const safe = raw.startsWith('/') && !raw.startsWith('//') ? raw : '/' 5 res.clearCookie('sk_return_to', { path: '/' }) 6 res.redirect(safe || '/dashboard') 7 }) ``` * Python Flask ```python 1 def callback(): 2 # ... exchange code ... 3 raw = request.cookies.get('sk_return_to', '/') 4 safe = raw if raw.startswith('/') and not raw.startswith('//') else '/' 5 resp = redirect(safe or '/dashboard') 6 resp.delete_cookie('sk_return_to', path='/') 7 return resp ``` * Go Gin ```go 1 func callback(c *gin.Context) { 2 // ... exchange code ... 3 raw, _ := c.Cookie("sk_return_to") 4 if raw == "" || !strings.HasPrefix(raw, "/") || strings.HasPrefix(raw, "//") { 5 raw = "/" 6 } 7 http.SetCookie(c.Writer, &http.Cookie{Name: "sk_return_to", Value: "", MaxAge: -1, Path: "/"}) 8 c.Redirect(http.StatusFound, raw) 9 } ``` * Java Spring ```java 1 public RedirectView callback(HttpServletRequest request, HttpServletResponse response) { 2 // ... exchange code ... 3 String raw = getCookie(request, "sk_return_to").orElse("/"); 4 boolean ok = raw.startsWith("/") && !raw.startsWith("//"); 5 Cookie clear = new Cookie("sk_return_to", ""); clear.setPath("/"); clear.setMaxAge(0); 6 response.addCookie(clear); 7 return new RedirectView(ok ? raw : "/dashboard"); 8 } ``` 4. ## Sign return\_to values Optional [Section titled “Sign return\_to values ”](#sign-return_to-values-) If you pass `return_to` via query string or store longer values, compute an HMAC and verify it before redirecting. Reject unsigned or invalid pairs. * Node.js HMAC signing ```javascript 1 import crypto from 'crypto' 2 function sign(value, secret) { 3 const mac = crypto.createHmac('sha256', secret).update(value).digest('base64url') 4 return `${value}|${mac}` 5 } 6 function verify(signed, secret) { 7 const [v, mac] = signed.split('|') 8 const good = crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(sign(v, secret).split('|')[1])) 9 return good ? v : null 10 } ``` * Python HMAC signing ```python 1 import hmac, hashlib, base64 2 def sign(value: str, secret: bytes) -> str: 3 mac = hmac.new(secret, value.encode(), hashlib.sha256).digest() 4 return f"{value}|{base64.urlsafe_b64encode(mac).decode().rstrip('=')}" 5 def verify(signed: str, secret: bytes) -> str | None: 6 try: 7 value, mac = signed.split('|', 1) 8 expected = sign(value, secret).split('|', 1)[1] 9 if hmac.compare_digest(mac, expected): 10 return value 11 except Exception: 12 pass 13 return None ``` * Go HMAC signing ```go 1 import ( 2 "crypto/hmac" 3 "crypto/sha256" 4 "encoding/base64" 5 ) 6 func sign(value string, secret []byte) string { 7 mac := hmac.New(sha256.New, secret) 8 mac.Write([]byte(value)) 9 sum := mac.Sum(nil) 10 return value + "|" + base64.RawURLEncoding.EncodeToString(sum) 11 } 12 func verify(signed string, secret []byte) *string { 13 parts := strings.SplitN(signed, "|", 2) 14 if len(parts) != 2 { return nil } 15 expected := strings.SplitN(sign(parts[0], secret), "|", 2)[1] 16 if hmac.Equal([]byte(parts[1]), []byte(expected)) { 17 return &parts[0] 18 } 19 return nil 20 } ``` * Java HMAC signing ```java 1 import javax.crypto.Mac; 2 import javax.crypto.spec.SecretKeySpec; 3 import java.util.Base64; 4 String sign(String value, byte[] secret) throws Exception { 5 Mac mac = Mac.getInstance("HmacSHA256"); 6 mac.init(new SecretKeySpec(secret, "HmacSHA256")); 7 byte[] raw = mac.doFinal(value.getBytes(StandardCharsets.UTF_8)); 8 String b64 = Base64.getUrlEncoder().withoutPadding().encodeToString(raw); 9 return value + "|" + b64; 10 } 11 String verify(String signed, byte[] secret) throws Exception { 12 String[] parts = signed.split("\\|", 2); 13 if (parts.length != 2) return null; 14 String expected = sign(parts[0], secret).split("\\|", 2)[1]; 15 return MessageDigest.isEqual(parts[1].getBytes(StandardCharsets.UTF_8), expected.getBytes(StandardCharsets.UTF_8)) ? parts[0] : null; 16 } ``` Limit scope and length Allowlist a small set of internal prefixes (for example, `/app`, `/billing`) and cap `return_to` length (for example, 512 chars). Reject anything else. Never redirect to external origins Allow only same-origin paths (e.g., `/billing`). Do not accept absolute URLs or protocol-relative URLs. This blocks open redirects. --- # DOCUMENT BOUNDARY --- # Set up SCIM connection > Set up a SCIM connection to your directory provider Scalekit supports user provisioning based on the [SCIM protocol](/directory/guides/user-provisioning-basics/). This allows your customers to manage their users automatically through directory providers, simplifying user access and revocation to your app when their employees join or leave an organization. By configuring their directory provider with your app via the Scalekit admin portal, customers can ensure seamless user management. 1. ## Enable SCIM provisioning for the organization [Section titled “Enable SCIM provisioning for the organization”](#enable-scim-provisioning-for-the-organization) The SCIM provisioning feature should be enabled for that particular organization. You can manually do this via the Scalekit dashboard > organization > overview. The other way, is to provide an option in your app so that organization admins (customers) can enable it within your app. Here’s how you can do that with Scalekit. Use the following SDK method to enable SCIM provisioning for the organization: * Node.js Enable SCIM ```javascript const settings = { features: [ { name: 'scim', enabled: true, } ], }; await scalekit.organization.updateOrganizationSettings( '', // Get this from the idToken or accessToken settings ); ``` * Python Enable SCIM ```python settings = [ { "name": "scim", "enabled": True } ] scalekit.organization.update_organization_settings( organization_id='', # Get this from the idToken or accessToken settings=settings ) ``` * Java Enable SCIM ```java OrganizationSettingsFeature featureSCIM = OrganizationSettingsFeature.newBuilder() .setName("scim") .setEnabled(true) .build(); updatedOrganization = scalekitClient.organizations() .updateOrganizationSettings(organizationId, List.of(featureSCIM)); ``` * Go Enable SCIM ```go settings := OrganizationSettings{ Features: []Feature{ { Name: "scim", Enabled: true, }, }, } organization, err := sc.Organization().UpdateOrganizationSettings(ctx, organizationId, settings) if err != nil { // Handle error } ``` Alternatively, enable SCIM provisioning from the Scalekit dashboard: navigate to Organizations, open the menu (⋯) for an organization, and check SCIM provisioning. 2. ## Enable admin portal for enterprise customer onboarding [Section titled “Enable admin portal for enterprise customer onboarding”](#enable-admin-portal-for-enterprise-customer-onboarding) After SCIM provisioning is enabled for that organization, provide a method for configuring a SCIM connection with the organization’s identity provider. Scalekit offers two primary approaches: * Generate a link to the admin portal from the Scalekit dashboard and share it with organization admins via your usual channels. * Or embed the admin portal in your application in an inline frame so administrators can configure their IdP without leaving your app. [See how to onboard enterprise customers](/directory/guides/onboard-enterprise-customers/) 3. ## Test your SCIM integration [Section titled “Test your SCIM integration”](#test-your-scim-integration) To verify that SCIM provisioning is working correctly, create a new user in the directory provider and confirm that it is automatically created in the Scalekit organization’s user list. To programmatically list the connected directories in your app, use the following SDK methods: * Node.js List connected directories ```javascript const { directories } = await scalekit.directory.listDirectories(''); ``` * Python List connected directories ```python directories = scalekit_client.directory.list_directories(organization_id='') ``` * Java List connected directories ```java ListDirectoriesResponse response = scalekitClient.directories().listDirectories(organizationId); ``` * Go List connected directories ```go directories, err := sc.Directory().ListDirectories(ctx, organizationId) ``` The response will be a list of connected directories, similar to the following: List connected directories response ```json { "directories": [ { "attribute_mappings": { "attributes": [] }, "directory_endpoint": "https://yourapp.scalekit.com/api/v1/directoies/dir_123212312/scim/v2", "directory_provider": "OKTA", "directory_type": "SCIM", "email": "john.doe@scalekit.cloud", "enabled": true, "groups_tracked": "ALL", "id": "dir_121312434123312", "last_synced_at": "2024-10-01T00:00:00Z", "name": "Azure AD", "organization_id": "org_121312434123312", "role_assignments": { "assignments": [ { "group_id": "dirgroup_121312434123", "role_name": "string" } ] }, "secrets": [ { "create_time": "2024-10-01T00:00:00Z", "directory_id": "dir_12362474900684814", "expire_time": "2025-10-01T00:00:00Z", "id": "string", "last_used_time": "2024-10-01T00:00:00Z", "secret_suffix": "Nzg5", "status": "INACTIVE" } ], "stats": { "group_updated_at": "2024-10-01T00:00:00Z", "total_groups": 10, "total_users": 10, "user_updated_at": "2024-10-01T00:00:00Z" }, "status": "IN_PROGRESS", "total_groups": 10, "total_users": 10 } ] } ``` 4. ## Enterprise users are now automatically provisioned your app [Section titled “Enterprise users are now automatically provisioned your app”](#enterprise-users-are-now-automatically-provisioned-your-app) Scalekit automatically provisions and synchronizes users from the directory provider to your application. The organization administrator configures the synchronization frequency within their directory provider console. To retrieve a list of all provisioned users, use the [Directory API](https://docs.scalekit.com/apis/#tag/directory/GET/api/v1/organizations/%7Borganization_id%7D/directories/%7Bdirectory_id%7D/users). --- # DOCUMENT BOUNDARY --- # Following webhook best practices > Learn best practices for implementing webhooks in your SCIM integration. Covers security measures, event handling, signature verification, and performance optimization techniques for real-time directory updates. Webhooks are HTTP endpoints that you register with a system, allowing that system to inform your application about events by sending HTTP POST requests with event information in the body. Developers register their applications’ webhook endpoints with Scalekit to listen to events from the directory providers of their enterprise customers. Here are some common best practices developers follow to ensure their apps are secure and performant: ## Subscribe only to relevant events [Section titled “Subscribe only to relevant events”](#subscribe-only-to-relevant-events) While you can listen to all events from Scalekit, it’s best to subscribe only to the events your app needs. This approach has several benefits: * Your app doesn’t have to process every event * You can avoid overloading a single execution context by handling every event type ## Verify webhook signatures [Section titled “Verify webhook signatures”](#verify-webhook-signatures) Scalekit sends POST requests to your registered webhook endpoint. Verify each request with the signing secret from **Dashboard > Webhooks > Any Endpoint** (`whsec_…`). Pass the raw body and these headers to the SDK: `webhook-id`, `webhook-timestamp`, and `webhook-signature`. * Node.js ```javascript 1 app.post( 2 '/webhook', 3 express.raw({ type: 'application/json' }), 4 async (req, res) => { 5 const secret = process.env.SCALEKIT_WEBHOOK_SECRET 6 const payload = req.body.toString() 7 const headers = { 8 'webhook-id': req.headers['webhook-id'], 9 'webhook-timestamp': req.headers['webhook-timestamp'], 10 'webhook-signature': req.headers['webhook-signature'], 11 } 12 13 try { 14 scalekit.verifyWebhookPayload(secret, headers, payload) 15 } catch (error) { 16 return res.status(401).json({ error: 'Invalid signature' }) 17 } 18 19 const event = JSON.parse(payload) 20 await processWebhookEvent(event) 21 return res.status(201).json({ received: true }) 22 } 23 ) ``` * Python ```python 1 import os 2 3 from fastapi import FastAPI, Request 4 from fastapi.responses import JSONResponse 5 6 app = FastAPI() 7 8 @app.post("/webhook") 9 async def api_webhook(request: Request): 10 # Get request data 11 body = await request.body() 12 13 # Extract webhook headers 14 headers = { 15 'webhook-id': request.headers.get('webhook-id'), 16 'webhook-signature': request.headers.get('webhook-signature'), 17 'webhook-timestamp': request.headers.get('webhook-timestamp') 18 } 19 20 try: 21 scalekit_client.verify_webhook_payload( 22 secret=os.environ["SCALEKIT_WEBHOOK_SECRET"], 23 headers=headers, 24 payload=body, 25 ) 26 except Exception: 27 return JSONResponse(status_code=401, content={"error": "Invalid signature"}) 28 29 return JSONResponse(status_code=201, content={"status": "received"}) ``` * Go ```go 1 mux.HandleFunc("POST /webhook", func(w http.ResponseWriter, r *http.Request) { 2 webhookSecret := os.Getenv("SCALEKIT_WEBHOOK_SECRET") 3 4 // Read request body 5 bodyBytes, err := io.ReadAll(r.Body) 6 if err != nil { 7 http.Error(w, err.Error(), http.StatusBadRequest) 8 return 9 } 10 11 // Prepare headers for verification 12 headers := map[string]string{ 13 "webhook-id": r.Header.Get("webhook-id"), 14 "webhook-signature": r.Header.Get("webhook-signature"), 15 "webhook-timestamp": r.Header.Get("webhook-timestamp"), 16 } 17 18 valid, err := scalekitClient.VerifyWebhookPayload( 19 webhookSecret, 20 headers, 21 bodyBytes, 22 ) 23 if err != nil || !valid { 24 http.Error(w, "Invalid signature", http.StatusUnauthorized) 25 return 26 } 27 }) ``` * Java ```java 1 @PostMapping("/webhook") 2 public ResponseEntity webhook( 3 @RequestBody String body, 4 @RequestHeader Map requestHeaders 5 ) { 6 // Spring may keep title-case keys. The Java SDK reads lowercase names only. 7 Map headers = new HashMap<>(); 8 headers.put("webhook-id", requestHeaders.get("webhook-id")); 9 headers.put("webhook-timestamp", requestHeaders.get("webhook-timestamp")); 10 headers.put("webhook-signature", requestHeaders.get("webhook-signature")); 11 12 String secret = System.getenv("SCALEKIT_WEBHOOK_SECRET"); 13 14 try { 15 scalekitClient.webhook().verifyWebhookPayload( 16 secret, 17 headers, 18 body.getBytes(java.nio.charset.StandardCharsets.UTF_8) 19 ); 20 } catch (Exception error) { 21 return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid signature"); 22 } 23 24 ObjectMapper mapper = new ObjectMapper(); 25 26 try { 27 // Parse event data 28 JsonNode node = mapper.readTree(body); 29 String eventType = node.get("type").asText(); 30 JsonNode data = node.get("data"); 31 32 // Handle different event types 33 switch (eventType) { 34 case "organization.directory.user_created": 35 handleUserCreate(data); 36 break; 37 case "organization.directory.user_updated": 38 handleUserUpdate(data); 39 break; 40 default: 41 System.out.println("Unhandled event type: " + eventType); 42 } 43 } catch (IOException e) { 44 return ResponseEntity.badRequest().body("error"); 45 } 46 47 return ResponseEntity.ok("ok"); 48 } ``` ## Check the event type before processing [Section titled “Check the event type before processing”](#check-the-event-type-before-processing) Make sure to check the event.type before consuming the data received by the webhook endpoint. This ensures that your application relies on accurate information, even if more events are added in the future. * Node.js ```javascript 1 app.post('/webhook', async (req, res) => { 2 const event = req.body; 3 4 // Handle different event types 5 switch (event.type) { 6 case 'organization.directory.user_created': 7 const { email, name } = event.data; 8 await createUserAccount(email, name); 9 break; 10 11 case 'organization.directory.user_updated': 12 await updateUserAccount(event.data); 13 break; 14 15 default: 16 console.log('Unhandled event type:', event.type); 17 } 18 19 return res.status(201).json({ 20 status: 'success', 21 }); 22 }); 23 24 async function createUserAccount(email, name) { 25 // Implement your user creation logic 26 } ``` * Python ```python 1 from fastapi import FastAPI, Request 2 3 app = FastAPI() 4 5 @app.post("/webhook") 6 async def api_webhook(request: Request): 7 # Parse request body 8 body = await request.body() 9 payload = json.loads(body.decode()) 10 event_type = payload['type'] 11 12 # Handle different event types 13 match event_type: 14 case 'organization.directory.user_created': 15 await handle_user_create(payload['data']) 16 case 'organization.directory.user_updated': 17 await handle_user_update(payload['data']) 18 case _: 19 print('Unhandled event type:', event_type) 20 21 return JSONResponse( 22 status_code=201, 23 content={'status': 'success'} 24 ) ``` * Go ```go 1 mux.HandleFunc("POST /webhook", func(w http.ResponseWriter, r *http.Request) { 2 // Read and verify webhook payload 3 bodyBytes, err := io.ReadAll(r.Body) 4 if err != nil { 5 http.Error(w, err.Error(), http.StatusBadRequest) 6 return 7 } 8 9 // Parse event data 10 var event map[string]interface{} 11 err = json.Unmarshal(bodyBytes, &event) 12 if err != nil { 13 http.Error(w, err.Error(), http.StatusBadRequest) 14 return 15 } 16 17 // Handle different event types 18 eventType := event["type"] 19 switch eventType { 20 case "organization.directory.user_created": 21 handleUserCreate(event["data"]) 22 case "organization.directory.user_updated": 23 handleUserUpdate(event["data"]) 24 default: 25 fmt.Println("Unhandled event type:", eventType) 26 } 27 28 w.WriteHeader(http.StatusOK) 29 }) ``` * Java ```java 1 @PostMapping("/webhook") 2 public ResponseEntity webhook( 3 @RequestBody String body, 4 @RequestHeader Map requestHeaders 5 ) { 6 Map headers = new HashMap<>(); 7 headers.put("webhook-id", requestHeaders.get("webhook-id")); 8 headers.put("webhook-timestamp", requestHeaders.get("webhook-timestamp")); 9 headers.put("webhook-signature", requestHeaders.get("webhook-signature")); 10 11 String secret = System.getenv("SCALEKIT_WEBHOOK_SECRET"); 12 try { 13 scalekitClient.webhook().verifyWebhookPayload( 14 secret, 15 headers, 16 body.getBytes(java.nio.charset.StandardCharsets.UTF_8) 17 ); 18 } catch (Exception error) { 19 return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid signature"); 20 } 21 22 try { 23 // Parse event data 24 ObjectMapper mapper = new ObjectMapper(); 25 JsonNode node = mapper.readTree(body); 26 String eventType = node.get("type").asText(); 27 JsonNode data = node.get("data"); 28 29 // Handle different event types 30 switch (eventType) { 31 case "organization.directory.user_created": 32 handleUserCreate(data); 33 break; 34 case "organization.directory.user_updated": 35 handleUserUpdate(data); 36 break; 37 default: 38 System.out.println("Unhandled event type: " + eventType); 39 } 40 } catch (IOException e) { 41 return ResponseEntity.badRequest().body("error"); 42 } 43 44 return ResponseEntity.ok("ok"); 45 } ``` ## Avoid webhook timeouts [Section titled “Avoid webhook timeouts”](#avoid-webhook-timeouts) To avoid unnecessary timeouts, respond to the webhook trigger with a response code of 201 and process the event asynchronously. By following these best practices, you can ensure that your application effectively handles events from Scalekit, maintaining optimal performance and security. ## Do not ignore errors [Section titled “Do not ignore errors”](#do-not-ignore-errors) Do not overlook repeated 4xx and 5xx error codes. Instead, verify that your API interactions are correct. For instance, if an endpoint expects a string but receives a numeric value, a validation error should occur. Likewise, trying to access an unauthorized or nonexistent endpoint will trigger a 4xx error. ## Manual verification without an SDK [Section titled “Manual verification without an SDK”](#manual-verification-without-an-sdk) Use the SDK when your language has one. If it does not, HMAC-SHA256 the string `{webhook-id}.{webhook-timestamp}.{rawBody}`. The key is the base64-decoded text after the first `_` in the `whsec_…` secret. The `webhook-signature` header is a space-separated list of `v1,` values. Reject timestamps more than 5 minutes in the past or future. Compare digests with a timing-safe function. Do not use Stripe-style `t=,v1=` headers, a `scalekit-signature` header, or a `sha256=` hex digest. Those are not Scalekit webhook signatures. See [Handle webhook events](/authenticate/implement-workflows/implement-webhooks/#verify-with-the-three-webhook-headers) for the SDK call. ## Advanced error handling and reliability [Section titled “Advanced error handling and reliability”](#advanced-error-handling-and-reliability) Implement comprehensive error handling to ensure reliable webhook processing across various failure scenarios. ### Retry logic with exponential backoff [Section titled “Retry logic with exponential backoff”](#retry-logic-with-exponential-backoff) Retry with exponential backoff ```javascript 1 async function processWebhookWithRetry(event, maxRetries = 3) { 2 for (let attempt = 1; attempt <= maxRetries; attempt++) { 3 try { 4 await processWebhookEvent(event); 5 return; // Success, exit retry loop 6 7 } catch (error) { 8 console.error(`Webhook processing attempt ${attempt} failed:`, error); 9 10 if (attempt === maxRetries) { 11 // Final attempt failed - log to dead letter queue 12 await deadLetterQueue.add('failed_webhook', { 13 event, 14 error: error.message, 15 attempts: attempt, 16 timestamp: new Date() 17 }); 18 throw error; 19 } 20 21 // Wait before retry with exponential backoff 22 // Attempt 1: 1s, Attempt 2: 2s, Attempt 3: 4s 23 const waitTime = Math.pow(2, attempt) * 1000; 24 await new Promise(resolve => setTimeout(resolve, waitTime)); 25 } 26 } 27 } ``` ### Circuit breaker pattern [Section titled “Circuit breaker pattern”](#circuit-breaker-pattern) Prevent cascading failures by implementing a circuit breaker: Circuit breaker for webhook processing ```javascript 1 class WebhookCircuitBreaker { 2 constructor(options = {}) { 3 this.failureThreshold = options.failureThreshold || 5; 4 this.recoveryTimeout = options.recoveryTimeout || 60000; // 60 seconds 5 this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN 6 this.failures = 0; 7 this.nextAttempt = Date.now(); 8 } 9 10 async execute(fn) { 11 if (this.state === 'OPEN') { 12 if (Date.now() < this.nextAttempt) { 13 throw new Error('Circuit breaker is OPEN'); 14 } 15 // Try to recover 16 this.state = 'HALF_OPEN'; 17 } 18 19 try { 20 const result = await fn(); 21 this.onSuccess(); 22 return result; 23 } catch (error) { 24 this.onFailure(); 25 throw error; 26 } 27 } 28 29 onSuccess() { 30 this.failures = 0; 31 this.state = 'CLOSED'; 32 } 33 34 onFailure() { 35 this.failures++; 36 if (this.failures >= this.failureThreshold) { 37 this.state = 'OPEN'; 38 this.nextAttempt = Date.now() + this.recoveryTimeout; 39 } 40 } 41 } 42 43 // Usage 44 const circuitBreaker = new WebhookCircuitBreaker({ 45 failureThreshold: 5, 46 recoveryTimeout: 60000 47 }); 48 49 async function handleWebhook(event) { 50 try { 51 await circuitBreaker.execute(async () => { 52 return await processWebhookEvent(event); 53 }); 54 } catch (error) { 55 if (error.message === 'Circuit breaker is OPEN') { 56 // Service is unhealthy, queue for later 57 await queueForLater(event); 58 } 59 throw error; 60 } 61 } ``` ## Advanced testing strategies [Section titled “Advanced testing strategies”](#advanced-testing-strategies) ### Webhook testing utilities [Section titled “Webhook testing utilities”](#webhook-testing-utilities) Create comprehensive testing utilities for your webhook handlers: Webhook testing utilities ```javascript 1 // Test webhook handler with sample events 2 async function testWebhookHandler() { 3 const sampleUserCreatedEvent = { 4 spec_version: '1', 5 id: 'evt_test_123', 6 type: 'organization.directory.user_created', 7 occurred_at: new Date().toISOString(), 8 environment_id: 'env_test_123', 9 organization_id: 'org_test_123', 10 object: 'DirectoryUser', 11 data: { 12 id: 'diruser_test_123', 13 organization_id: 'org_test_123', 14 email: 'test@example.com', 15 given_name: 'Test', 16 family_name: 'User', 17 active: true, 18 groups: [], 19 roles: [] 20 } 21 }; 22 23 // Test your webhook processing 24 await processWebhookEvent(sampleUserCreatedEvent); 25 console.log('Test webhook processed successfully'); 26 } ``` ## Monitoring and debugging [Section titled “Monitoring and debugging”](#monitoring-and-debugging) ### Webhook delivery monitoring [Section titled “Webhook delivery monitoring”](#webhook-delivery-monitoring) Track webhook processing metrics to identify issues and optimize performance: Webhook monitoring ```javascript 1 // Track webhook processing metrics 2 async function trackWebhookMetrics(event, processingTime, success) { 3 await metricsService.record('webhook_processed', { 4 event_type: event.type, 5 processing_time_ms: processingTime, 6 success: success, 7 organization_id: event.organization_id, 8 environment_id: event.environment_id, 9 timestamp: new Date() 10 }); 11 12 // Alert on processing time anomalies 13 if (processingTime > 5000) { // 5 seconds 14 await alertService.warn({ 15 message: 'Slow webhook processing detected', 16 eventType: event.type, 17 processingTime: processingTime, 18 eventId: event.id 19 }); 20 } 21 22 // Alert on failures 23 if (!success) { 24 await alertService.error({ 25 message: 'Webhook processing failed', 26 eventType: event.type, 27 eventId: event.id 28 }); 29 } 30 } 31 32 // Dashboard endpoint to view webhook statistics 33 app.get('/admin/webhook-stats', async (req, res) => { 34 const stats = await db.query(` 35 SELECT 36 event_type, 37 COUNT(*) as total_events, 38 SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as successful, 39 SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed, 40 AVG(processing_time_ms) as avg_processing_time, 41 MAX(processing_time_ms) as max_processing_time, 42 MIN(processing_time_ms) as min_processing_time 43 FROM processed_webhooks 44 WHERE processed_at > NOW() - INTERVAL 24 HOUR 45 GROUP BY event_type 46 ORDER BY total_events DESC 47 `); 48 49 res.json(stats); 50 }); 51 52 // Real-time webhook monitoring 53 async function monitorWebhookHealth() { 54 const recentFailures = await db.processed_webhooks.count({ 55 where: { 56 status: 'failed', 57 processed_at: { 58 $gte: new Date(Date.now() - 5 * 60 * 1000) // Last 5 minutes 59 } 60 } 61 }); 62 63 if (recentFailures > 10) { 64 await alertService.critical({ 65 message: 'High webhook failure rate detected', 66 failureCount: recentFailures, 67 timeWindow: '5 minutes' 68 }); 69 } 70 } 71 72 // Run health check every minute 73 setInterval(monitorWebhookHealth, 60000); ``` ### Debugging webhook issues [Section titled “Debugging webhook issues”](#debugging-webhook-issues) Webhook debugging utilities ```javascript 1 // Detailed webhook logging 2 async function logWebhookDetails(event, context) { 3 await db.webhook_logs.create({ 4 event_id: event.id, 5 event_type: event.type, 6 organization_id: event.organization_id, 7 environment_id: event.environment_id, 8 received_at: new Date(), 9 headers: context.headers, 10 payload: event, 11 ip_address: context.ip, 12 user_agent: context.userAgent 13 }); 14 } 15 16 // Webhook replay for debugging 17 async function replayWebhook(eventId) { 18 // Retrieve original webhook from logs 19 const webhookLog = await db.webhook_logs.findOne({ 20 event_id: eventId 21 }); 22 23 if (!webhookLog) { 24 throw new Error(`Webhook ${eventId} not found`); 25 } 26 27 // Replay the webhook 28 console.log(`Replaying webhook ${eventId}`); 29 await processWebhookEvent(webhookLog.payload); 30 console.log(`Webhook ${eventId} replayed successfully`); 31 } 32 33 // Dead letter queue processor for failed webhooks 34 async function processDeadLetterQueue() { 35 const failedWebhooks = await deadLetterQueue.getAll('failed_webhook'); 36 37 for (const item of failedWebhooks) { 38 try { 39 console.log(`Reprocessing failed webhook: ${item.event.id}`); 40 await processWebhookEvent(item.event); 41 42 // Remove from dead letter queue on success 43 await deadLetterQueue.remove('failed_webhook', item.id); 44 45 } catch (error) { 46 console.error(`Failed to reprocess webhook ${item.event.id}:`, error); 47 48 // Increment retry count 49 item.retries = (item.retries || 0) + 1; 50 51 if (item.retries >= 5) { 52 // Move to permanent failure queue 53 await permanentFailureQueue.add(item); 54 await deadLetterQueue.remove('failed_webhook', item.id); 55 } 56 } 57 } 58 } 59 60 // Run dead letter queue processor periodically 61 setInterval(processDeadLetterQueue, 5 * 60 * 1000); // Every 5 minutes ``` ### Performance optimization [Section titled “Performance optimization”](#performance-optimization) Webhook performance optimization ```javascript 1 // Batch processing for high-volume webhooks 2 class WebhookBatchProcessor { 3 constructor(options = {}) { 4 this.batchSize = options.batchSize || 100; 5 this.flushInterval = options.flushInterval || 5000; // 5 seconds 6 this.queue = []; 7 this.timer = null; 8 } 9 10 add(event) { 11 this.queue.push(event); 12 13 if (this.queue.length >= this.batchSize) { 14 this.flush(); 15 } else if (!this.timer) { 16 this.timer = setTimeout(() => this.flush(), this.flushInterval); 17 } 18 } 19 20 async flush() { 21 if (this.queue.length === 0) return; 22 23 const batch = this.queue.splice(0, this.batchSize); 24 clearTimeout(this.timer); 25 this.timer = null; 26 27 try { 28 await this.processBatch(batch); 29 } catch (error) { 30 console.error('Batch processing error:', error); 31 // Re-queue failed items 32 this.queue.unshift(...batch); 33 } 34 } 35 36 async processBatch(events) { 37 // Process multiple events efficiently 38 await db.transaction(async (trx) => { 39 // Bulk insert processed events 40 await trx('processed_webhooks').insert( 41 events.map(e => ({ 42 event_id: e.id, 43 event_type: e.type, 44 organization_id: e.organization_id, 45 status: 'processing', 46 received_at: new Date() 47 })) 48 ); 49 50 // Process events in parallel 51 await Promise.all(events.map(e => this.processEvent(e, trx))); 52 }); 53 } 54 55 async processEvent(event, trx) { 56 // Event-specific processing logic 57 // Use transaction for atomicity 58 } 59 } 60 61 // Usage 62 const batchProcessor = new WebhookBatchProcessor({ 63 batchSize: 100, 64 flushInterval: 5000 65 }); 66 67 app.post('/webhooks/manage-users', async (req, res) => { 68 // Verify signature... 69 const event = req.body; 70 71 // Add to batch processor 72 batchProcessor.add(event); 73 74 // Respond immediately 75 return res.status(201).json({ received: true }); 76 }); ``` By following these advanced best practices, you can build a robust, reliable, and performant webhook integration that handles high volumes of events while maintaining data consistency and security. --- # DOCUMENT BOUNDARY --- # The Auth Stack for your SaaS > Add SSO, SCIM, or MCP Auth as modular capabilities, or adopt Scalekit as your full identity layer for your SaaS app # The Auth Stack for your SaaS Add auth to your B2B SaaS application without building from scratch. Drop in a modular capability like MCP Auth, Single Sign-On, or SCIM alongside your existing system, or adopt Scalekit as your full identity layer for users, sessions, organizations, and roles. Building auth from scratch? Start with [SaaS User Management](/authenticate/fsa/quickstart). Adding SSO, SCIM, or MCP Auth to an existing system? Use [Modular Auth](/authenticate/mcp/quickstart/). 2 steps · \~5 minutes · works with any AI coding agent * Claude Code Install the authstack plugin ```bash npx @scalekit-inc/cli setup ``` For repeated use: `npm install -g @scalekit-inc/cli` then `scalekit setup`. Then load the shipped skill `implement-saaskit`. [Full setup guide →](/dev-kit/build-with-ai/full-stack-auth/) * Codex Install the authstack plugin ```bash npx @scalekit-inc/cli setup ``` For repeated use: `npm install -g @scalekit-inc/cli` then `scalekit setup`. Restart Codex, open the Plugin Directory, and enable the Scalekit plugins you need. Then load the shipped skill `implement-saaskit`. [Full setup guide →](/dev-kit/build-with-ai/full-stack-auth/) * GitHub Copilot CLI Install the authstack plugin ```bash npx @scalekit-inc/cli setup ``` For repeated use: `npm install -g @scalekit-inc/cli` then `scalekit setup`. Then load the shipped skill `implement-saaskit`. [Full setup guide →](/dev-kit/build-with-ai/full-stack-auth/) * Cursor Install the authstack plugin ```bash npx @scalekit-inc/cli setup ``` For repeated use: `npm install -g @scalekit-inc/cli` then `scalekit setup`. Restart Cursor (or run **Developer: Reload Window**), then enable the Scalekit plugins in Settings. Then load the shipped skill `implement-saaskit`. [Full setup guide →](/dev-kit/build-with-ai/full-stack-auth/) * 40+ agents Install the authstack plugin ```bash npx @scalekit-inc/cli setup ``` For repeated use: `npm install -g @scalekit-inc/cli` then `scalekit setup`. Choose the “Other agents” / skills option when prompted by the CLI. Then load the shipped skill `implement-saaskit`. [Full setup guide →](/dev-kit/build-with-ai/full-stack-auth/) Need help? [Join the developer community](https://join.slack.com/t/scalekit-community/shared_invite/zt-3gsxwr4hc-0tvhwT2b_qgVSIZQBQCWRw) or browse the [guides](/guides/). ## Modular auth Add specific auth capabilities like MCP Auth, SSO, or SCIM without replacing your existing system. ### [MCP Auth](/authenticate/mcp/quickstart/) [Add OAuth 2.1 authorization to your remote MCP server with Dynamic Client Registration and short-lived tokens](/authenticate/mcp/quickstart/) ### [Single Sign-On](/authenticate/sso/add-modular-sso/) [Let enterprise users sign in through their company’s identity provider like Okta, Microsoft Entra, Google, and more](/authenticate/sso/add-modular-sso/) ### [SCIM Provisioning](/directory/scim/quickstart/) [Automatically sync users, roles, and groups when IT admins add or remove people in Okta or Microsoft Entra](/directory/scim/quickstart/) ## SaaS user management Use Scalekit as your full identity layer to manage users, organizations, sessions, roles, and application access. [Quickstart](/authenticate/fsa/quickstart) Get production-ready auth running in minutes ![SaaS User Management](/_astro/image-pills.uCLDErHA.svg) ### [User lifecycle](/fsa/data-modelling) [Create, update, and delete users with built-in lifecycle APIs](/fsa/data-modelling) ### [Authentication methods](/authenticate/auth-methods/passwordless/) [Support modern login flows with passkeys, magic links, OTPs, and social logins](/authenticate/auth-methods/passwordless/) ### [B2B-native identity](/fsa/data-modelling) [Model organizations, user memberships, and multi-tenant access for B2B SaaS apps](/fsa/data-modelling) ### [Authorization](/authenticate/authz/overview) [Define roles and permissions for human users and AI agents](/authenticate/authz/overview) ### [Enterprise identity](/authenticate/auth-methods/enterprise-sso) [Add enterprise capabilities like Single Sign-On (SSO) and SCIM provisioning](/authenticate/auth-methods/enterprise-sso) ### [API & M2M auth](/authenticate/m2m/api-auth-quickstart) [Issue and validate user-scoped and org-level tokens for APIs and services](/authenticate/m2m/api-auth-quickstart) ## Extensibility & Controls Customize identity workflows and apply your business logic. ### [Webhooks](/authenticate/implement-workflows/implement-webhooks/) [Receive real-time events for authentication, user lifecycle, and organizations](/authenticate/implement-workflows/implement-webhooks/) ### [Interceptors](/authenticate/interceptors/auth-flow-interceptors/) [Apply custom logic and policy checks during authentication and authorization flows](/authenticate/interceptors/auth-flow-interceptors/) ### [Branding](/fsa/guides/login-page-branding/) [Customize hosted login and signup pages plus auth emails to match your app](/fsa/guides/login-page-branding/) ### [Auth logs](/guides/dashboard/auth-logs/) [Record and inspect authentication events and user access activity for auditing purposes](/guides/dashboard/auth-logs/) ## Developer Resources SDKs, code samples, and community resources for building with Scalekit. ### [SDKs](/apis/#description/sdks) [Drop-in libraries to quickly integrate Scalekit into your application](/apis/#description/sdks) ### [Code samples](/resources/code-samples) [Reference implementations and code examples for common auth flows](/resources/code-samples) ### [Developer community](https://join.slack.com/t/scalekit-community/shared_invite/zt-3gsxwr4hc-0tvhwT2b_qgVSIZQBQCWRw) [Ask questions, share feedback, and learn from other Scalekit developers](https://join.slack.com/t/scalekit-community/shared_invite/zt-3gsxwr4hc-0tvhwT2b_qgVSIZQBQCWRw) ## Security, Compliance & Availability Designed for production workloads with strict operational and security requirements. ⊕**Multi-region data residency**\ Dedicated regional clusters in the US and EU ⊕**Compliance**\ SOC 2, ISO 27001, GDPR, and CCPA compliant ⊕**Uptime**\ 99.99% uptime with failover redundancy ⊕**Secure token & secret storage**\ Vault-backed storage with strong isolation for tokens and credentials ![Compliance certifications](/_astro/compliance.G4CWsxzs.svg) --- # DOCUMENT BOUNDARY --- # Bring Your Own Auth > Using Scalekit as a drop-in OAuth 2.1 authorization layer for your MCP Servers with federated authentication to your existing auth layer. Scalekit also offers the option to integrate your existing authentication infrastructure with Scalekit’s OAuth layer for MCP servers. **Use this when you have an existing auth system and want to add MCP OAuth without migrating users.** When your B2B application already has an established authentication system, you can connect it to your MCP server through Scalekit. This ensures that: * Users see the same familiar login screen whether accessing your application or your MCP server * No user migration required - your existing user accounts work immediately with MCP * You maintain control over your authentication logic while gaining MCP OAuth 2.1 compliance This “bring your own auth” approach standardizes the authorization layer without requiring you to rebuild your existing authentication infrastructure from scratch. Update your login endpoint for MCP token exchange The following changes will need to be made in your B2B apps’s Login API Endpoint. The connection ID, User POST URL and Redirect URI allows your app to know that scalekit is attempting to perform the Token Exchange for MCP Auth, so the user should get redirected to the correct consent screen post MCP Login instead of your B2B app. ## Step-by-Step Workflow [Section titled “Step-by-Step Workflow”](#step-by-step-workflow) When an MCP client initiates an authentication flow, Scalekit redirects to your login endpoint. You then provide user details to Scalekit via a secure backend call, and finally redirect back to Scalekit to complete the process. ### 1. Initiate Authentication [Section titled “1. Initiate Authentication”](#1-initiate-authentication) * The MCP client starts the authentication flow by calling `/oauth/authorize` on Scalekit. * Scalekit redirects the user to your login endpoint, passing two parameters: * `login_request_id`: Unique identifier for the login request. * `state`: Value to maintain state between requests. Example Redirect URL ```txt https://app.example.com/login?login_request_id=lri_86659065219908156&state=HntJ_ENB6y161i9_P1yzuZVv2SSTfD3aZH-Tej0_Y33_Fk8Z3g ``` ### 2. Handle Authentication in Your Application [Section titled “2. Handle Authentication in Your Application”](#2-handle-authentication-in-your-application) Once the user lands on your login page: #### a. Authenticate the User [Section titled “a. Authenticate the User”](#a-authenticate-the-user) Take the user through your regular authentication logic (e.g., username/password, SSO, etc.). #### b. Send User Details to Scalekit [Section titled “b. Send User Details to Scalekit”](#b-send-user-details-to-scalekit) Send the authenticated user’s profile details from your backend to Scalekit to complete the login handshake. * Python ```bash 1 pip install scalekit-sdk-python ``` send\_user\_details.py ```python 1 from scalekit import ScalekitClient 2 import os 3 4 scalekit_client = ScalekitClient( 5 os.environ.get('SCALEKIT_ENVIRONMENT_URL'), 6 os.environ.get('SCALEKIT_CLIENT_ID'), 7 os.environ.get('SCALEKIT_CLIENT_SECRET') 8 ) 9 10 # Update login user details 11 try: 12 response = scalekit_client.auth.update_login_user_details( 13 connection_id="{{connection_id}}", 14 login_request_id="{{login_request_id}}", 15 user={ 16 "sub": "1234567890", 17 "email": "alice@example.com" 18 }, 19 ) 20 except Exception: 21 # Handle the request/SDK failure (network error, invalid credentials, etc.) 22 # and stop — do NOT redirect back to Scalekit on a failed request. 23 raise 24 25 # response is a (message, grpc.Call) tuple; the auth request ID (req_xxx) is on the first element. 26 auth_request_id = response[0].auth_request_id 27 # Optional: paste auth_request_id into Scalekit Dashboard > Auth Logs 28 # to view the entire auth journey for this login. 29 30 # To report a failed login instead, send login_failed=True (sub/email not required): 31 # scalekit_client.auth.update_login_user_details( 32 # connection_id="{{connection_id}}", 33 # login_request_id="{{login_request_id}}", 34 # user={"login_failed": True}, 35 # ) ``` * Node.js ```bash 1 npm install @scalekit-sdk/node ``` sendUserDetails.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 // Initialize client 4 const scalekit = new Scalekit( 5 process.env.SCALEKIT_ENVIRONMENT_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET 8 ); 9 10 // Update login user details 11 let res; 12 try { 13 res = await scalekit.auth.updateLoginUserDetails( 14 '{{connection_id}}', // connectionId 15 '{{login_request_id}}', // loginRequestId 16 { 17 sub: '1234567890', 18 email: 'alice@example.com' 19 } 20 ); 21 } catch (err) { 22 // Handle the request/SDK failure (network error, invalid credentials, etc.) 23 // and stop — do NOT redirect back to Scalekit on a failed request. 24 throw err; 25 } 26 27 // The response carries the auth request ID (req_xxx). 28 const authRequestId = res.authRequestId; 29 // Optional: paste authRequestId into Scalekit Dashboard > Auth Logs 30 // to view the entire auth journey for this login. 31 32 // To report a failed login instead, send loginFailed: true (sub/email not required): 33 // await scalekit.auth.updateLoginUserDetails( 34 // '{{connection_id}}', 35 // '{{login_request_id}}', 36 // { loginFailed: true } 37 // ); ``` * Go ```bash 1 go get -u github.com/scalekit-inc/scalekit-sdk-go ``` send\_user\_details.go ```go 1 import ( 2 "context" 3 "fmt" 4 "github.com/scalekit-inc/scalekit-sdk-go/v2" 5 "os" 6 ) 7 8 // Get the connectionId from ScaleKit dashboard -> MCP Server -> Your Server -> User Info Post Url 9 // eg. https://example.scalekit.dev/api/v1/connections/conn_70982106544698372/auth-requests/{{login_request_id}}/user 10 // Your connectionId is conn_70982106544698372 in this example 11 func updateLoggedInUserDetails() error { 12 scalekitClient := scalekit.NewScalekitClient( 13 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 14 os.Getenv("SCALEKIT_CLIENT_ID"), 15 os.Getenv("SCALEKIT_CLIENT_SECRET"), 16 ) 17 resp, err := scalekitClient.Auth().UpdateLoginUserDetails(context.Background(), &scalekit.UpdateLoginUserDetailsRequest{ 18 ConnectionId: "{{connection_id}}", 19 LoginRequestId: "{{login_request_id}}", // this value is dynamic per login 20 User: &scalekit.LoggedInUserDetails{ 21 Sub: "1234567890", 22 Email: "alice@example.com", 23 }, 24 }) 25 if err != nil { 26 return err 27 } 28 29 // The response carries the auth request ID (req_xxx). 30 authRequestId := resp.GetAuthRequestId() 31 fmt.Println("auth request id:", authRequestId) 32 // Optional: paste authRequestId into Scalekit Dashboard -> Auth Logs 33 // to view the entire auth journey for this login. 34 35 // To report a failed login instead, send LoginFailed: true (Sub/Email not required): 36 // _, err = scalekitClient.Auth().UpdateLoginUserDetails(context.Background(), &scalekit.UpdateLoginUserDetailsRequest{ 37 // ConnectionId: "{{connection_id}}", 38 // LoginRequestId: "{{login_request_id}}", 39 // User: &scalekit.LoggedInUserDetails{LoginFailed: true}, 40 // }) 41 42 // Only if there is no error, perform the redirect to scalekit using the redirect url on your Scalekit Dashboard -> MCP Servers 43 return nil 44 } ``` * Java pom.xml ```xml 1 2 com.scalekit 3 scalekit-sdk-java 4 2.3.0 5 ``` SendUserDetails.java ```java 1 import com.scalekit.ScalekitClient; 2 import com.scalekit.grpc.scalekit.v1.auth.User; 3 import com.scalekit.internal.http.UpdateLoginUserDetailsResult; 4 import com.scalekit.shaded.google.protobuf.Struct; 5 import com.scalekit.shaded.google.protobuf.Value; 6 7 public class SendUserDetails { 8 9 // Returns the auth request ID (req_xxx) for the login request. 10 public String sendUserDetails(String connectionId, String loginRequestId, boolean loginSucceeded) { 11 ScalekitClient scalekitClient = new ScalekitClient( 12 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 13 System.getenv("SCALEKIT_CLIENT_ID"), 14 System.getenv("SCALEKIT_CLIENT_SECRET") 15 ); 16 17 User user; 18 if (loginSucceeded) { 19 Struct customAttributes = Struct.newBuilder() 20 .putFields("access_level", Value.newBuilder().setNumberValue(101).build()) 21 .putFields("subscription_type", Value.newBuilder().setStringValue("PREMIUM").build()) 22 .build(); 23 24 user = User.newBuilder() 25 .setSub("user_123") 26 .setEmail("test@example.com") 27 .setName("Test User") 28 .addRoles("support") 29 .addRoles("developer") 30 .setCustomAttributes(customAttributes) 31 .build(); 32 } else { 33 // Report a failed login — sub/email are not required when loginFailed is true. 34 user = User.newBuilder().setLoginFailed(true).build(); 35 } 36 37 try { 38 UpdateLoginUserDetailsResult result = 39 scalekitClient.login().updateLoginUserDetails(connectionId, loginRequestId, user); 40 // The auth request ID (req_xxx). Optionally store it to fetch events for this auth 41 // request later, or paste it into Scalekit Dashboard > Auth Logs to view the entire 42 // auth journey for this login. 43 return result.getAuthRequestId(); 44 } catch (Exception e) { 45 // Handle the request/SDK failure (network error, invalid credentials, etc.) and 46 // stop — do NOT redirect back to Scalekit on a failed request. 47 throw new RuntimeException("Failed to update login user details", e); 48 } 49 } 50 } ``` * cURL Acquire an `access_token` before you could send user details by hitting the `/oauth/token` endpoint. You can get `env_url`, `sk_client_id` and `sk_client_secret` from *Scalekit Dashboard > Settings* get\_access\_token.sh ```bash 1 # --fail-with-body makes curl exit non-zero on an HTTP error so a failed token 2 # request is distinguishable from a successful one. 3 curl --fail-with-body --location '{{env_url}}/oauth/token' \ 4 --header 'Content-Type: application/x-www-form-urlencoded' \ 5 --data-urlencode 'grant_type=client_credentials' \ 6 --data-urlencode 'client_id={{sk_client_id}}' \ 7 --data-urlencode 'client_secret={{sk_client_secret}}' ``` Scalekit responds with a JSON payload similar to: ```json 1 { 2 "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIn0...", 3 "token_type": "Bearer", 4 "expires_in": 3600 5 } ``` Use the `access_token` in the `Authorization` header when making a machine-to-machine POST request to Scalekit with the user’s details. send\_user\_details.sh ```bash 1 # --fail-with-body makes curl exit non-zero (and still print the body) on an HTTP 2 # error, so a failed request is distinguishable from a successful one. 3 curl --fail-with-body --location '{{env_url}}/api/v1/connections/{{connection_id}}/auth-requests/{{login_request_id}}/user' \ 4 --header 'Content-Type: application/json' \ 5 --header 'Authorization: Bearer {{access_token}}' \ 6 --data-raw '{ 7 "sub": "1234567890", 8 "email": "alice@example.com", 9 "roles": ["support", "developer"], 10 "custom_attributes": { 11 "access_level": 101, 12 "subscription_type": "PREMIUM" 13 } 14 }' ``` *** ### 3. Redirect Back to Scalekit [Section titled “3. Redirect Back to Scalekit”](#3-redirect-back-to-scalekit) * Once you receive a successful response from Scalekit, redirect the user back to Scalekit using the provided `state` value to the below endpoint. **Example Redirect URL:** ```txt {{envurl}}/sso/v1/connections/{{connection_id}}/partner:callback?state={{state_value}} ``` `state_value` should match the `state` parameter you received in Step 1. *** ### 4. Completion [Section titled “4. Completion”](#4-completion) * After processing the callback from your auth system, Scalekit will handle the remaining steps (showing the consent screen to the user, token exchange, etc.) automatically. **Try out the BYOA MCP server**: Clone the [byoa-mcp-node sample](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/byoa-mcp-node) — a working Node.js MCP server with a custom login page, Scalekit token validation, and custom claims flowing through to tool handlers. Follow the README to run it locally end-to-end. --- # DOCUMENT BOUNDARY --- # Secure MCP with Enterprise SSO > Use Scalekit's out-of-the-box enterprise SSO connections to authenticate your MCP server from first request. Scalekit automatically handles identity verification via any authentication method, including but not limited to social providers like Google and Microsoft. It also supports authentication with your enterprise identity provider, such as Okta, Microsoft Entra AD, or ADFS, via SAML or OIDC. In this article, we will explain how to configure an Enterprise SSO connection with Okta as an identity provider. You can follow the same steps to configure any other identity provider. The steps with **blue arrows indicate that the step occurs during the browser redirects** and the steps with the **red arrows are Headless or Machine-to-Machine operations happening in the background.** ## Understanding the MCP SSO Flow at a high level [Section titled “Understanding the MCP SSO Flow at a high level”](#understanding-the-mcp-sso-flow-at-a-high-level) ## Before you start [Section titled “Before you start”](#before-you-start) Please make sure you have implemented MCP Auth with any of these [examples](/authenticate/mcp/fastmcp-quickstart). ## Configure Okta for authentication [Section titled “Configure Okta for authentication”](#configure-okta-for-authentication) 1. To configure Enterprise SSO, you need to create an organization.\ Open the **[Scalekit Dashboard](https://app.scalekit.com)** -> **Organizations** -> **Create Organization**. ![Create Organization](/.netlify/images?url=_astro%2Fcreate-org.CcRUR9lM.png\&w=1328\&h=818\&dpl=6aaa70ad2ea7b40008ad2afd) 2. Navigate to the **Single Sign-On** tab and follow the on-screen instructions. Make sure to click **Test Connection**, and then **Enable Connection**. ![Setup Organization SSO](/.netlify/images?url=_astro%2Fsetup-org-sso.DKNJlLtE.png\&w=832\&h=1424\&dpl=6aaa70ad2ea7b40008ad2afd) 3. To enforce that users from this organization are authenticated with the identity provider, add the domain under the **Domains** section in the **Overview** tab (e.g., `acmecorp.com`). ![Organization Domain Setup](/.netlify/images?url=_astro%2Forg-domain.BY_Mm5M_.png\&w=2582\&h=1146\&dpl=6aaa70ad2ea7b40008ad2afd) You have successfully implemented Enterprise SSO for your MCP server. Try running any of the [example apps](/authenticate/mcp/fastmcp-quickstart) next. [Explore More Enterprise SSO Providers](/guides/integrations/sso-integrations) --- # DOCUMENT BOUNDARY --- # Secure MCP with Social Logins > Use Scalekit's out-of-the-box social connections to authenticate your MCP server from the first request. Scalekit supports a variety of social connections out of the box, such as Google, Microsoft, GitHub, GitLab, LinkedIn, and Salesforce. This section focuses on how to use Google authentication, and the same process can be used for other social connections. ## Before you start [Section titled “Before you start”](#before-you-start) Please make sure you have implemented MCP auth with any of these [examples](/authenticate/mcp/fastmcp-quickstart). ## Configure Google connection [Section titled “Configure Google connection”](#configure-google-connection) 1. To configure the Google connection, open **[Dashboard](https://app.scalekit.com)** -> navigate to the **Authentication** section -> select **Auth Methods** -> select **Social Login**, and click on the **Edit** button against **Google**. 2. You can select **Use Scalekit credentials**, or you can follow the on-screen instructions to bring your own Google credentials. ![Google Auth Method](/.netlify/images?url=_astro%2Fgoogle-setup-enable.Qu9_1oNn.png\&w=3018\&h=902\&dpl=6aaa70ad2ea7b40008ad2afd) You have successfully implemented the social connection for your MCP server. Try running any of the [example apps](/authenticate/mcp/fastmcp-quickstart) next. [Explore More Social Providers](/guides/integrations/social-connections/) --- # DOCUMENT BOUNDARY --- # Secure MCP with Cross-App Access (XAA) > Use your customer's enterprise IdP to broker short-lived, scoped access to your MCP server, with no long-lived keys and no code changes required. Cross-App Access (XAA) lets your customer’s enterprise identity provider (IdP), such as Okta, act as the trust broker for your MCP server. Instead of storing long-lived API keys or requiring individual OAuth consent flows, an AI agent presents a signed identity assertion from the enterprise IdP. Scalekit exchanges that assertion for a short-lived, scoped access token, which the agent uses to call your MCP server. The enterprise admin authorizes the connector once. All users in the relevant IdP groups inherit access automatically, and every token request is logged through the IdP’s existing audit trail. ## How Cross-App Access works [Section titled “How Cross-App Access works”](#how-cross-app-access-works) 1. The AI agent requests an **identity assertion (ID-JAG)** from the enterprise IdP. The IdP can be any provider that supports XAA - Okta, Microsoft Entra, or others. 2. The IdP returns a **signed ID-JAG JWT** containing standard claims: issuer (`iss`), subject (`sub`), audience (`aud`), and expiry (`exp`). 3. The agent exchanges the ID-JAG at Scalekit’s `/oauth/token` endpoint using the JWT Bearer grant (`grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`). 4. Scalekit validates the JWT’s signature, issuer trust, and audience, then enforces the configured scopes and returns a **short-lived access token**. 5. The agent calls your **MCP server** with the Bearer token. Your server validates it exactly as it does today, with no code changes required. ## Enable Cross-App Access [Section titled “Enable Cross-App Access”](#enable-cross-app-access) 1. Open the **[Scalekit Dashboard](https://app.scalekit.com)**. 2. Navigate to **Auth for SaaS > MCP Servers**. 3. Select your MCP server. 4. Toggle on **Enable Cross-App Access (XAA)**. ## Supported MCP clients [Section titled “Supported MCP clients”](#supported-mcp-clients) XAA works with all three registration types that Scalekit supports: * **DCR clients** (Dynamic Client Registration) - Public clients such as Claude Desktop, Cursor, and VS Code that auto-register are fully supported. No additional configuration is needed. * **CIMD clients** (Client ID Metadata Document) - Clients that use a metadata URL as their identifier are also supported with XAA automatically. * **Pre-registered confidential clients** - If your MCP client requires a fixed `client_id` and `client_secret`, [pre-register the client in the Scalekit dashboard](/authenticate/mcp/managing-mcp-clients/) and provide your customer with the client id and secret for them to configure in their MCP clients. ## When to use XAA [Section titled “When to use XAA”](#when-to-use-xaa) * **No secret sprawl** - agents never store persistent API keys; tokens are short-lived and scoped to specific operations. * **Central IdP governance** - the enterprise IdP is the single control plane for all agent access, with a unified audit trail. * **One-time admin setup** - an admin authorizes the connector once; all users in the mapped groups inherit access without individual consent flows. --- # DOCUMENT BOUNDARY --- # Passwordless OIDC Quickstart > Add passwordless sign-in with OTP or magic link via OIDC Implement passwordless authentication with Scalekit over the OIDC protocol. Users verify their identity with an email verification code (OTP) or a magic link. Using a coding agent?Copy SaaSKit prompt 1. ## Set up Scalekit and register a callback endpoint [Section titled “Set up Scalekit and register a callback endpoint”](#set-up-scalekit-and-register-a-callback-endpoint) Follow the [installation guide](/authenticate/set-up-scalekit/) to configure Scalekit in your application. Scalekit verifies user identities and creates sessions. After successful verification, Scalekit creates a user record and sends the user information to your callback endpoint. **Create a callback endpoint:** 1. Add a callback endpoint to your application (typically `https://your-app.com/auth/callback`) 2. Register this URL in your Scalekit dashboard Learn more about [callback URL requirements](/guides/dashboard/redirects/#allowed-callback-urls). 2. ## Configure passwordless settings [Section titled “Configure passwordless settings”](#configure-passwordless-settings) In the Scalekit dashboard, enable Magic link & OTP and choose your login method. Optional security settings: * **Enforce same-browser origin**: Users must complete magic-link auth in the same browser they started in. * **Issue new credentials on resend**: Each resend generates a fresh code or link and invalidates the previous one. ![Scalekit dashboard Magic link & OTP settings showing the login method selection and expiry period fields](/.netlify/images?url=_astro%2F1.1jnMxeBv.png\&w=3024\&h=1612\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ## Redirect users to sign up (or) login [Section titled “Redirect users to sign up (or) login”](#redirect-users-to-sign-up-or-login) Create an authorization URL and redirect users to Scalekit’s sign-in page. Include: | Parameter | Description | | -------------- | --------------------------------------------------------------------------------- | | `redirect_uri` | Your app’s callback endpoint (for example, `https://your-app.com/auth/callback`). | | `client_id` | Your Scalekit application identifier (scoped to the environment). | | `login_hint` | The user’s email address to receive the verification email. | **Example implementation** * Node.js ```javascript 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 // Initialize the SDK client 3 const scalekit = new ScalekitClient( 4 '', 5 '', 6 '', 7 ); 8 9 const options = {}; 10 11 options['loginHint'] = 'user@example.com'; 12 13 const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); 14 // Generated URL will look like: 15 // https:///oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile%20email&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback 16 17 res.redirect(authorizationUrl); ``` * Python ```python 1 from scalekit import ScalekitClient, AuthorizationUrlOptions, CodeAuthenticationOptions 2 3 # Initialize the SDK client 4 scalekit = ScalekitClient( 5 '', 6 '', 7 '' 8 ) 9 10 options = AuthorizationUrlOptions() 11 12 # Authorization URL with login hint 13 options.login_hint = 'user@example.com' 14 15 authorization_url = scalekit.get_authorization_url(redirect_uri, options) 16 # Generated URL will look like: 17 # https:///oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile%20email&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback 18 19 return redirect(authorization_url) ``` * Go ```go 1 import ( 2 "github.com/scalekit-inc/scalekit-sdk-go" 3 ) 4 5 func main() { 6 // Initialize the SDK client 7 scalekitClient := scalekit.NewScalekitClient( 8 "", 9 "", 10 "" 11 ) 12 13 options := scalekitClient.AuthorizationUrlOptions{} 14 // User's email domain detects the correct enterprise SSO connection. 15 options.LoginHint = "user@example.com" 16 17 authorizationURL := scalekitClient.GetAuthorizationUrl( 18 redirectUrl, 19 options, 20 ) 21 // Next step is to redirect the user to this authorization URL 22 } 23 24 // Redirect the user to this authorization URL ``` * Java ```java 1 package com.scalekit; 2 3 import com.scalekit.ScalekitClient; 4 import com.scalekit.internal.http.AuthorizationUrlOptions; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 // Initialize the SDK client 10 ScalekitClient scalekitClient = new ScalekitClient( 11 "", 12 "", 13 "" 14 ); 15 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 16 // User's email domain detects the correct enterprise SSO connection. 17 options.setLoginHint("user@example.com"); 18 try { 19 String url = scalekitClient 20 .authentication() 21 .getAuthorizationUrl(redirectUrl, options) 22 .toString(); 23 } catch (Exception e) { 24 System.out.println(e.getMessage()); 25 } 26 } 27 } 28 // Redirect the user to this authorization URL ``` This redirects users to Scalekit’s authentication flow. After verification, they return to your application. At your `redirect_uri`, handle the callback to exchange the code for the user profile. Ensure this URL is registered as an Allowed Callback URI in the dashboard. 4. ## Get user details from the callback [Section titled “Get user details from the callback”](#get-user-details-from-the-callback) Scalekit redirects to your `redirect_uri` with an authorization code. Exchange it server-side for the user’s profile. Validation attempt limits To protect your application, Scalekit limits a user to **five** attempts to enter the correct OTP within a ten-minute window for each authentication request. If the user exceeds this limit, they must restart the authentication process. Always perform the code exchange on the server to validate the code and return the authenticated user’s profile. * Node.js Fetch user profile ```javascript 1 // Handle oauth redirect_url, fetch code and error_description from request params 2 const { code, error, error_description } = req.query; 3 4 if (error) { 5 // Handle errors 6 } 7 8 const result = await scalekit.authenticateWithCode(code, redirectUri); 9 const userEmail = result.user.email; 10 11 // Next step: create a session for this user and allow access ``` * Python Fetch user profile ```py 1 # Handle oauth redirect_url, fetch code and error_description from request params 2 code = request.args.get('code') 3 error = request.args.get('error') 4 error_description = request.args.get('error_description') 5 6 if error: 7 raise Exception(error_description) 8 9 result = scalekit.authenticate_with_code(code, '') 10 11 # result.user has the authenticated user's details 12 user_email = result.user.email 13 14 # Next step: create a session for this user and allow access ``` * Go Fetch user profile ```go 1 // Handle oauth redirect_url, fetch code and error_description from request params 2 code := r.URL.Query().Get("code") 3 errorCode := r.URL.Query().Get("error") 4 errorDescription := r.URL.Query().Get("error_description") 5 6 if errorCode != "" { 7 // Handle errors - include errorDescription for context 8 return fmt.Errorf("OAuth error: %s - %s", errorCode, errorDescription) 9 } 10 11 result, err := scalekitClient.AuthenticateWithCode(r.Context(), code, redirectUrl) 12 13 if err != nil { 14 // Handle errors 15 } 16 17 // result.User has the authenticated user's details 18 userEmail := result.User.Email 19 20 // Next step: create a session for this user and allow access ``` * Java Fetch user profile ```java 1 // Handle oauth redirect_url, fetch code and error_description from request params 2 String code = request.getParameter("code"); 3 String error = request.getParameter("error"); 4 String errorDescription = request.getParameter("error_description"); 5 6 if (error != null && !error.isEmpty()) { 7 // Handle errors 8 return; 9 } 10 11 try { 12 AuthenticationResponse result = scalekit.authentication().authenticateWithCode(code, redirectUrl); 13 String userEmail = result.getIdTokenClaims().getEmail(); 14 15 // Next step: create a session for this user and allow access 16 } catch (Exception e) { 17 // Handle errors 18 } ``` The `result` object * Result object ```js { user: { email: "john.doe@example.com" // Authenticated user's email address }, idToken: "", // ID token (JWT) containing user profile claims accessToken: "", // Access token (JWT) for calling backend APIs on behalf of the user expiresIn: 899 // Time in seconds } ``` * Decoded ID token ```json { "alg": "RS256", "kid": "snk_82937465019283746", "typ": "JWT" }.{ "amr": [ "conn_92847563920187364" ], "at_hash": "j8kqPm3nRt5Kx2Vy9wL_Zp", "aud": [ "skc_73645291837465928" ], "azp": "skc_73645291837465928", "c_hash": "Hy4k2M9pWnX7vqR8_Jt3bg", "client_id": "skc_73645291837465928", "email": "alice.smith@example.com", "email_verified": true, "exp": 1751697469, "iat": 1751438269, "iss": "https://demo-company-dev.scalekit.cloud", "sid": "ses_83746592018273645", "sub": "conn_92847563920187364;alice.smith@example.com" // A scalekit user ID is sent if user management is enabled }.[Signature] ``` * Decoded access token ```json { "alg": "RS256", "kid": "snk_794467716206433", "typ": "JWT" }.{ "iss": "https://acme-corp-dev.scalekit.cloud", "sub": "conn_794467724427269;robert.wilson@acme.com", "aud": [ "skc_794467724259497" ], "exp": 1751439169, "iat": 1751438269, "nbf": 1751438269, "client_id": "skc_794467724259497", "jti": "tkn_794754665320942", // External identifiers if updated on Scalekit "xoid": "ext_org_123", // Organization ID "xuid": "ext_usr_456" // User ID }.[Signature] ``` Congratulations! Your application now supports passwordless authentication. Users can sign in securely by: * Entering a verification code sent to their email * Clicking a magic link sent to their email To complete the implementation, [create a session](/authenticate/fsa/manage-session/) for the user to allow access to protected resources. --- # DOCUMENT BOUNDARY --- # UI events from the embedded admin portal > Learn how to listen for and handle UI events from the embedded admin portal, such as SSO connection status and session expiration. The embedded admin portal emits browser events that allow your application to respond to configuration changes made by organization admins. Use these events to provide real-time feedback, update your UI, sync configuration state, or trigger workflows in your application. Common use cases include displaying success notifications when SSO is configured, refreshing authentication settings after directory sync is enabled, or prompting users to re-authenticate when their admin portal session expires. ## Listening to admin portal events [Section titled “Listening to admin portal events”](#listening-to-admin-portal-events) Add an event listener to your parent window to receive events from the embedded admin portal iframe: ```js 1 window.addEventListener('message', (event) => { 2 // Security: Always validate the event origin matches your Scalekit environment 3 if (event.origin !== 'https://your-env.scalekit.com') { 4 return; // Ignore events from untrusted sources 5 } 6 7 // Check if this is a valid admin portal event 8 if (event.data && event.data.event_type) { 9 const { event_type, organization_id, data } = event.data; 10 11 // Handle specific event types 12 switch (event_type) { 13 case 'ORGANIZATION_SSO_ENABLED': 14 // Show success notification, refresh SSO settings, etc. 15 showNotification('SSO enabled successfully'); 16 break; 17 18 case 'PORTAL_SESSION_EXPIRY': 19 // Prompt user to refresh the admin portal 20 promptSessionRefresh(); 21 break; 22 23 default: 24 console.log('Received event:', event.data); 25 } 26 } 27 }); ``` Security requirement The domain of your parent window must be listed in **Dashboard > API Config > Redirect URIs** for the admin portal to emit events. Always validate `event.origin` to ensure events come from your trusted Scalekit environment URL. *** ## SSO events [Section titled “SSO events”](#sso-events) ### `ORGANIZATION_SSO_ENABLED` [Section titled “ORGANIZATION\_SSO\_ENABLED”](#organization_sso_enabled) Fires when an organization admin successfully enables a Single Sign-On connection in the admin portal. ORGANIZATION\_SSO\_ENABLED ```json 1 { 2 "event_type": "ORGANIZATION_SSO_ENABLED", 3 "object": "connection", 4 "organization_id": "org_4010340X34236531", // Organization that enabled SSO 5 "message": "Single sign-on connection enabled successfully", 6 "data": { 7 "connection_type": "SSO", 8 "id": "conn_4256075523X312", // Connection ID for API calls 9 "type": "OIDC", // Protocol: OIDC or SAML 10 "provider": "OKTA", // Identity provider configured 11 "enabled": true 12 } 13 } ``` | Field | Type | Description | | ---------------------- | ------- | ------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.connection_type` | string | Type of connection (SSO) | | `data.id` | string | Unique identifier for the connection | | `data.type` | string | Protocol type (e.g., OIDC, SAML) | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the connection is enabled | ### `ORGANIZATION_SSO_DISABLED` [Section titled “ORGANIZATION\_SSO\_DISABLED”](#organization_sso_disabled) Fires when an organization admin disables their Single Sign-On connection in the admin portal. ORGANIZATION\_SSO\_DISABLED ```json 1 { 2 "event_type": "ORGANIZATION_SSO_DISABLED", 3 "object": "connection", 4 "organization_id": "org_4010340X34236531", // Organization that disabled SSO 5 "message": "Single sign-on connection disabled successfully", 6 "data": { 7 "connection_type": "SSO", 8 "id": "conn_4256075523X312", // Connection ID that was disabled 9 "type": "OIDC", // Protocol: OIDC or SAML 10 "provider": "OKTA", // Identity provider that was configured 11 "enabled": false 12 } 13 } ``` | Field | Type | Description | | ---------------------- | ------- | ------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.connection_type` | string | Type of connection (SSO) | | `data.id` | string | Unique identifier for the connection | | `data.type` | string | Protocol type (e.g., OIDC, SAML) | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the connection is enabled | ## Session events [Section titled “Session events”](#session-events) ### `PORTAL_LOAD_SUCCESS` [Section titled “PORTAL\_LOAD\_SUCCESS”](#portal_load_success) Fires when the admin portal session is created and loaded successfully. Use this event to display the portal iframe and confirm readiness to users. PORTAL\_LOAD\_SUCCESS ```json 1 { 2 "event_type": "PORTAL_LOAD_SUCCESS", 3 "object": "session", 4 "message": "The admin portal loaded successfully", 5 "organization_id": "org_43982563588440584", 6 "data": { 7 "expiry": "2025-02-28T12:40:35.911Z" // ISO 8601 timestamp when session expires 8 } 9 } ``` | Field | Type | Description | | ----------------- | ------ | ---------------------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.expiry` | string | ISO 8601 timestamp indicating when the session will expire | ### `PORTAL_LOAD_FAILURE` [Section titled “PORTAL\_LOAD\_FAILURE”](#portal_load_failure) Fires when the admin portal session failed to load. Use this to prompt users that the session has failed to load. PORTAL\_LOAD\_FAILURE ```json 1 { 2 "event_type": "PORTAL_LOAD_FAILURE", 3 "object": "session", 4 "message": "The admin portal failed to load", 5 "data": { 6 "error_code": "SESSION_EXPIRED" // error code indicating why the session load failed 7 } 8 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `message` | string | Human-readable message describing the event | | `data.error_code` | string | Error code indicating why the session load failed | ### `PORTAL_SESSION_WARNING` [Section titled “PORTAL\_SESSION\_WARNING”](#portal_session_warning) Fires when the admin portal session is about to expire (typically 5 minutes before expiration). Use this to prompt users to save their work or refresh their session. PORTAL\_SESSION\_WARNING ```json 1 { 2 "event_type": "PORTAL_SESSION_WARNING", 3 "object": "session", 4 "message": "The admin portal session will expire in 5 minutes", 5 "organization_id": "org_43982563588440584", 6 "data": { 7 "expiry": "2025-02-28T12:40:35.911Z" // ISO 8601 timestamp when session expires 8 } 9 } ``` | Field | Type | Description | | ----------------- | ------ | ---------------------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.expiry` | string | ISO 8601 timestamp indicating when the session will expire | ### `PORTAL_SESSION_EXPIRY` [Section titled “PORTAL\_SESSION\_EXPIRY”](#portal_session_expiry) Fires when the admin portal session has expired. Use this to hide the admin portal iframe and prompt users to re-authenticate. PORTAL\_SESSION\_EXPIRY ```json 1 { 2 "event_type": "PORTAL_SESSION_EXPIRY", 3 "object": "session", 4 "message": "The admin portal session has expired", 5 "organization_id": "org_43982563588440584", 6 "data": { 7 "expiry": "2025-02-28T12:40:35.911Z" // ISO 8601 timestamp when session expired 8 } 9 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------ | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.expiry` | string | ISO 8601 timestamp indicating when the session expired | ## Directory events [Section titled “Directory events”](#directory-events) ### `ORGANIZATION_DIRECTORY_ENABLED` [Section titled “ORGANIZATION\_DIRECTORY\_ENABLED”](#organization_directory_enabled) Fires when an organization admin successfully configures and enables SCIM directory provisioning in the admin portal. ORGANIZATION\_DIRECTORY\_ENABLED ```json 1 { 2 "event_type": "ORGANIZATION_DIRECTORY_ENABLED", 3 "object": "directory", 4 "organization_id": "org_45716217859670289", // Organization that enabled directory sync 5 "message": "SCIM Provisioning enabled successfully", 6 "data": { 7 "directory_type": "SCIM", // Directory protocol type 8 "id": "dir_45716228982964495", // Directory connection ID for API calls 9 "provider": "MICROSOFT_AD", // Identity provider: OKTA, AZURE_AD, GOOGLE, etc. 10 "enabled": true 11 } 12 } ``` | Field | Type | Description | | --------------------- | ------- | ---------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.directory_type` | string | Type of directory synchronization (SCIM) | | `data.id` | string | Unique identifier for the directory connection | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the directory sync is enabled | ### `ORGANIZATION_DIRECTORY_DISABLED` [Section titled “ORGANIZATION\_DIRECTORY\_DISABLED”](#organization_directory_disabled) Fires when an organization admin disables SCIM directory provisioning in the admin portal. ORGANIZATION\_DIRECTORY\_DISABLED ```json 1 { 2 "event_type": "ORGANIZATION_DIRECTORY_DISABLED", 3 "object": "directory", 4 "organization_id": "org_45716217859670289", // Organization that disabled directory sync 5 "message": "SCIM Provisioning disabled successfully", 6 "data": { 7 "directory_type": "SCIM", // Directory protocol type 8 "id": "dir_45716228982964495", // Directory connection ID that was disabled 9 "provider": "MICROSOFT_AD", // Identity provider that was configured 10 "enabled": false 11 } 12 } ``` | Field | Type | Description | | --------------------- | ------- | ---------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.directory_type` | string | Type of directory synchronization (SCIM) | | `data.id` | string | Unique identifier for the directory connection | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the directory sync is enabled | ## Complete event handler Example [Section titled “Complete event handler ”](#complete-event-handler-) Here’s a complete example showing how to handle all admin portal events in a production application: Complete admin portal event handler ```js 1 // Initialize event handling for the admin portal 2 function initAdminPortalEventHandling(scalekitEnvironmentUrl) { 3 window.addEventListener('message', (event) => { 4 // Security: Validate event origin 5 if (event.origin !== scalekitEnvironmentUrl) { 6 return; 7 } 8 9 if (!event.data || !event.data.event_type) { 10 return; 11 } 12 13 const { event_type, organization_id, data, message } = event.data; 14 15 // Log all events for debugging 16 console.log('[Admin Portal Event]', { event_type, organization_id, data }); 17 18 switch (event_type) { 19 case 'ORGANIZATION_SSO_ENABLED': 20 handleSSOEnabled(organization_id, data); 21 break; 22 23 case 'ORGANIZATION_SSO_DISABLED': 24 handleSSODisabled(organization_id, data); 25 break; 26 27 case 'ORGANIZATION_DIRECTORY_ENABLED': 28 handleDirectoryEnabled(organization_id, data); 29 break; 30 31 case 'ORGANIZATION_DIRECTORY_DISABLED': 32 handleDirectoryDisabled(organization_id, data); 33 break; 34 35 case 'PORTAL_LOAD_SUCCESS': 36 handlePortalLoadSuccess(data.expiry); 37 break; 38 39 case 'PORTAL_LOAD_FAILURE': 40 handlePortalLoadFailure(data.error_code); 41 break; 42 43 case 'PORTAL_SESSION_WARNING': 44 handleSessionWarning(data.expiry); 45 break; 46 47 case 'PORTAL_SESSION_EXPIRY': 48 handleSessionExpiry(); 49 break; 50 51 default: 52 console.warn('Unknown event type:', event_type); 53 } 54 }); 55 } 56 57 function handleSSOEnabled(orgId, data) { 58 // Show success notification 59 showToast('success', `SSO enabled successfully with ${data.provider}`); 60 61 // Sync configuration to your backend 62 fetch('/api/organizations/${orgId}/sync-sso', { 63 method: 'POST', 64 headers: { 'Content-Type': 'application/json' }, 65 body: JSON.stringify({ connectionId: data.id, provider: data.provider }) 66 }); 67 68 // Update UI to reflect SSO is active 69 updateOrganizationUI(orgId, { ssoEnabled: true }); 70 } 71 72 function handlePortalLoadSuccess(expiryTime) { 73 const expiryDate = new Date(expiryTime); 74 console.log('[Admin Portal] Loaded successfully, session expires at', expiryDate); 75 76 // Update UI to show the portal is ready 77 document.getElementById('admin-portal-iframe').style.display = 'block'; 78 } 79 80 function handlePortalLoadFailure(errorCode) { 81 console.error('[Admin Portal] Failed to load, error code:', errorCode); 82 83 // Hide the iframe and show an error message to the user 84 document.getElementById('admin-portal-iframe').style.display = 'none'; 85 86 showModal({ 87 title: 'Portal failed to load', 88 message: errorCode === 'SESSION_EXPIRED' 89 ? 'Your session has expired. Please refresh to continue.' 90 : `The admin portal could not be loaded (${errorCode}). Please try again.`, 91 action: { 92 label: 'Refresh Page', 93 onClick: () => window.location.reload() 94 } 95 }); 96 } 97 98 function handleSessionWarning(expiryTime) { 99 const expiryDate = new Date(expiryTime); 100 const minutesLeft = Math.round((expiryDate - new Date()) / 60000); 101 102 showNotification({ 103 type: 'warning', 104 message: `Your admin session will expire in ${minutesLeft} minutes`, 105 action: { 106 label: 'Refresh Session', 107 onClick: () => window.location.reload() 108 } 109 }); 110 } 111 112 function handleSessionExpiry() { 113 // Hide the admin portal iframe 114 document.getElementById('admin-portal-iframe').style.display = 'none'; 115 116 // Show message to user 117 showModal({ 118 title: 'Session Expired', 119 message: 'Your admin portal session has expired. Please refresh to continue.', 120 action: { 121 label: 'Refresh Page', 122 onClick: () => window.location.reload() 123 } 124 }); 125 } 126 127 // Initialize when your app loads 128 initAdminPortalEventHandling('https://your-env.scalekit.com'); ``` --- # DOCUMENT BOUNDARY --- # BigQuery (Service Account) Connect to BigQuery using a GCP service account for server-to-server authentication without user login. ![BigQuery (Service Account) logo](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg) Supports authentication: Service Account ## Create a Connection [Section titled “Create a Connection”](#create-a-connection) In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Find **BigQuery (Service Account)** and click **Create**. That’s it — no OAuth credentials or redirect URIs needed. BigQuery Service Account uses server-to-server authentication handled entirely through your GCP service account credentials. ## Create a Connected Account [Section titled “Create a Connected Account”](#create-a-connected-account) To connect a BigQuery account programmatically, you need a GCP service account JSON key. Here’s how to get one: 1. ### Create a GCP service account * Go to [Google Cloud Console](https://console.cloud.google.com) → **IAM & Admin** → **Service Accounts**. * Click **+ Create Service Account**, enter a name and description, and click **Create and Continue**. * Grant the service account the **BigQuery Data Viewer**, **BigQuery Data Editor**, and **BigQuery Job User** roles, then click **Done**. 2. ### Enable the BigQuery API * In [Google Cloud Console](https://console.cloud.google.com), go to **APIs & Services** → **Library**. * Search for **BigQuery API** and click **Enable**. ![Enable BigQuery API in Google Cloud Console](/.netlify/images?url=_astro%2Fenable-bigquery-api.B6BUg3wp.png\&w=1398\&h=498\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ### Download the service account JSON key * In the Service Accounts list, click on your service account. * Go to the **Keys** tab → **Add Key** → **Create new key**. * Select **JSON** and click **Create**. The key file downloads automatically. * Use the contents of this file as the `service_account_json` value when creating a connected account. ## Usage [Section titled “Usage”](#usage) ## Tool list [Section titled “Tool list”](#tool-list) ## `bigqueryserviceaccount_get_dataset` [Section titled “bigqueryserviceaccount\_get\_dataset”](#bigqueryserviceaccount_get_dataset) Retrieve metadata for a specific BigQuery dataset, including location, description, labels, access controls, and creation/modification times. | Name | Type | Required | Description | | ------------ | ------ | -------- | --------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset to retrieve | ## `bigqueryserviceaccount_get_job` [Section titled “bigqueryserviceaccount\_get\_job”](#bigqueryserviceaccount_get_job) Retrieve the status and configuration of a BigQuery job by its job ID. Use this to poll for completion of an async query job. | Name | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------------------------------ | | `job_id` | string | Yes | The ID of the job to retrieve | | `location` | string | No | Geographic location where the job was created, e.g. US or EU | ## `bigqueryserviceaccount_get_model` [Section titled “bigqueryserviceaccount\_get\_model”](#bigqueryserviceaccount_get_model) Retrieve metadata for a specific BigQuery ML model, including model type, feature columns, label columns, and training run details. | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------ | | `dataset_id` | string | Yes | The ID of the dataset containing the model | | `model_id` | string | Yes | The ID of the model to retrieve | ## `bigqueryserviceaccount_get_query_results` [Section titled “bigqueryserviceaccount\_get\_query\_results”](#bigqueryserviceaccount_get_query_results) Retrieve the results of a completed BigQuery query job. Supports pagination via page tokens. Use after polling Get Job until status is DONE. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------------------ | | `job_id` | string | Yes | The ID of the completed query job | | `location` | string | No | Geographic location where the job was created, e.g. US or EU | | `max_results` | integer | No | Maximum number of rows to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page of results | | `timeout_ms` | integer | No | Maximum milliseconds to wait if the query has not yet completed | ## `bigqueryserviceaccount_get_routine` [Section titled “bigqueryserviceaccount\_get\_routine”](#bigqueryserviceaccount_get_routine) Retrieve the definition and metadata of a specific BigQuery routine (stored procedure or UDF), including its arguments, return type, and body. | Name | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset containing the routine | | `routine_id` | string | Yes | The ID of the routine to retrieve | ## `bigqueryserviceaccount_get_table` [Section titled “bigqueryserviceaccount\_get\_table”](#bigqueryserviceaccount_get_table) Retrieve metadata and schema for a specific BigQuery table or view, including column names, types, descriptions, and table properties. | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------ | | `dataset_id` | string | Yes | The ID of the dataset containing the table | | `table_id` | string | Yes | The ID of the table or view to retrieve | ## `bigqueryserviceaccount_list_datasets` [Section titled “bigqueryserviceaccount\_list\_datasets”](#bigqueryserviceaccount_list_datasets) List all BigQuery datasets in the project. Supports filtering by label and pagination. | Name | Type | Required | Description | | ------------- | ------- | -------- | ----------------------------------------------------------------- | | `all` | boolean | No | If true, includes hidden datasets in the results | | `filter` | string | No | Label filter expression to restrict results, e.g. labels.env:prod | | `max_results` | integer | No | Maximum number of datasets to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_list_jobs` [Section titled “bigqueryserviceaccount\_list\_jobs”](#bigqueryserviceaccount_list_jobs) List BigQuery jobs in the project. Supports filtering by state and projection, and pagination. | Name | Type | Required | Description | | -------------- | ------- | -------- | -------------------------------------------------------------------------------------------------- | | `all_users` | boolean | No | If true, returns jobs for all users in the project; otherwise returns only the current user’s jobs | | `max_results` | integer | No | Maximum number of jobs to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | | `projection` | string | No | Controls the fields returned: minimal (default) or full | | `state_filter` | string | No | Filter jobs by state: done, pending, or running | ## `bigqueryserviceaccount_list_models` [Section titled “bigqueryserviceaccount\_list\_models”](#bigqueryserviceaccount_list_models) List all BigQuery ML models in a dataset, including their model type, training status, and creation time. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset to list models from | | `max_results` | integer | No | Maximum number of models to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_list_routines` [Section titled “bigqueryserviceaccount\_list\_routines”](#bigqueryserviceaccount_list_routines) List all stored procedures and user-defined functions (UDFs) in a BigQuery dataset. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------------------ | | `dataset_id` | string | Yes | The ID of the dataset to list routines from | | `filter` | string | No | Filter expression to restrict results, e.g. routineType:SCALAR\_FUNCTION | | `max_results` | integer | No | Maximum number of routines to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_list_table_data` [Section titled “bigqueryserviceaccount\_list\_table\_data”](#bigqueryserviceaccount_list_table_data) Read rows directly from a BigQuery table without writing a SQL query. Supports pagination, row offset, and field selection. | Name | Type | Required | Description | | ----------------- | ------- | -------- | ---------------------------------------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset containing the table | | `max_results` | integer | No | Maximum number of rows to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | | `selected_fields` | string | No | Comma-separated list of fields to return; if omitted all fields are returned | | `start_index` | integer | No | Zero-based row index to start reading from | | `table_id` | string | Yes | The ID of the table to read rows from | ## `bigqueryserviceaccount_list_tables` [Section titled “bigqueryserviceaccount\_list\_tables”](#bigqueryserviceaccount_list_tables) List all tables and views in a BigQuery dataset. Supports pagination. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset to list tables from | | `max_results` | integer | No | Maximum number of tables to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_run_query` [Section titled “bigqueryserviceaccount\_run\_query”](#bigqueryserviceaccount_run_query) Execute a SQL query synchronously against BigQuery and return results immediately. Best for short-running queries. | Name | Type | Required | Description | | ---------------- | ------- | -------- | ------------------------------------------------------------------------------------ | | `create_session` | boolean | No | If true, creates a new session and returns a session ID in the response | | `dry_run` | boolean | No | If true, validates the query and returns estimated bytes processed without executing | | `location` | string | No | Geographic location of the dataset, e.g. US or EU | | `max_results` | integer | No | Maximum number of rows to return in the response | | `query` | string | Yes | SQL query to execute | | `timeout_ms` | integer | No | Maximum milliseconds to wait for query completion before returning | | `use_legacy_sql` | boolean | No | Use BigQuery legacy SQL syntax instead of standard SQL | --- # DOCUMENT BOUNDARY --- # Box > Connect to Box to manage files, folders, users, tasks, webhooks, collaborations, and more using OAuth 2.0. Connect to Box to manage files, folders, users, groups, collaborations, tasks, comments, webhooks, search, and more using the Box REST API. ![Box logo](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg) Supports authentication: OAuth 2.0 ![Box connector shown in Scalekit's Create Connection search](/.netlify/images?url=_astro%2Fscalekit-search-box.C0z6eJsp.png\&w=1200\&h=800\&dpl=6aaa70ad2ea7b40008ad2afd) ## Set up the agent connector [Section titled “Set up the agent connector”](#set-up-the-agent-connector) Connect Box to Scalekit so your agent can manage files, folders, users, tasks, and more on behalf of your users. Box uses OAuth 2.0 — users authorize access through Box’s login flow, and Scalekit handles token storage and refresh automatically. You will need: * A Box developer account (free at [developer.box.com](https://developer.box.com)) * Your Box OAuth app’s Client ID and Client Secret * The redirect URI from Scalekit to paste into Box 1. ### Create a Box OAuth app * Go to the [Box Developer Console](https://app.box.com/developers/console) and click **Create New App**. * Select **Custom App** as the app type. * Under authentication method, choose **User Authentication (OAuth 2.0)**. This lets your agent act on behalf of each user who authorizes access. * Enter an app name (e.g. “My Agent App”) and click **Create App**. ![](/.netlify/images?url=_astro%2Fbox-create-app.wHE_wZtb.png\&w=1200\&h=900\&dpl=6aaa70ad2ea7b40008ad2afd) 2. ### Copy the redirect URI from Scalekit * In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. * Find **Box** and click **Create**. * Click **Use your own credentials** and copy the redirect URI. It looks like: `https://.scalekit.cloud/sso/v1/oauth//callback` ![](/.netlify/images?url=_astro%2Fscalekit-search-box.C0z6eJsp.png\&w=1200\&h=800\&dpl=6aaa70ad2ea7b40008ad2afd) 3. ### Add the redirect URI to Box * In the [Box Developer Console](https://app.box.com/developers/console), open your app and go to the **Configuration** tab. * Under **OAuth 2.0 Redirect URI**, paste the redirect URI from Scalekit and click **Save Changes**. ![](/.netlify/images?url=_astro%2Fbox-dev-console.6d84g8vH.png\&w=1200\&h=800\&dpl=6aaa70ad2ea7b40008ad2afd) 4. ### Select scopes for your app Still on the **Configuration** tab in Box, scroll down to **Application Scopes** and enable the permissions your agent needs: | Scope | Required for | | ------------------------------ | ---------------------------------------------- | | `root_readonly` | Reading files and folders | | `root_readwrite` | Creating, updating, and deleting files/folders | | `manage_groups` | Creating and managing groups | | `manage_webhook` | Creating and managing webhooks | | `manage_managed_users` | Creating and managing enterprise users | | `manage_enterprise_properties` | Accessing enterprise events | Click **Save Changes** after selecting scopes. 5. ### Add credentials in Scalekit * In the [Box Developer Console](https://app.box.com/developers/console), open your app → **Configuration** tab. * Copy your **Client ID** and **Client Secret**. * In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections**, open the Box connection you created, and enter: * **Client ID** — from Box * **Client Secret** — from Box * **Scopes** — select the same scopes you enabled in Box (e.g. `root_readonly`, `root_readwrite`) ![](/.netlify/images?url=_astro%2Fadd-credentials.Cw-vm376.png\&w=1200\&h=800\&dpl=6aaa70ad2ea7b40008ad2afd) * Click **Save**. 6. ### Add a connected account for each user Each user who authorizes Box access becomes a connected account. During authorization, Box will show your app name and request the scopes you configured. **Via dashboard (for testing)** * In [Scalekit dashboard](https://app.scalekit.com), go to your Box connection → **Connected Accounts** → **Add Account**. * Enter a **User ID** (your internal identifier for this user, e.g. `user_123`). * Click **Add** — you will be redirected to Box’s OAuth consent screen to authorize. ![](/.netlify/images?url=_astro%2Fadd-connected-account.CS-N7oE6.png\&w=1200\&h=800\&dpl=6aaa70ad2ea7b40008ad2afd) **Via API (for production)** In production, generate an authorization link and redirect your user to it: * Node.js ```typescript 1 const { link } = await scalekit.actions.getAuthorizationLink({ 2 connectionName: 'box', 3 identifier: 'user_123', 4 }); 5 // Redirect your user to `link` ``` * Python ```python 1 link_response = scalekit_client.actions.get_authorization_link( 2 connection_name="box", 3 identifier="user_123", 4 ) 5 # Redirect your user to link_response.link ``` After the user authorizes, Scalekit stores their tokens. Your agent can then call Box tools on their behalf without any further redirects. ## Usage [Section titled “Usage”](#usage) ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most Box tools require an ID for the resource they operate on. Here is where to find each ID: | Resource | Tool to get ID | Response field | | ------------------- | ------------------------------------------------------------------ | -------------------------------------------------------- | | File ID | `box_folder_items_list` (folder\_id: `"0"`) | `entries[].id` where `entries[].type == "file"` | | Folder ID | `box_folder_items_list` (folder\_id: `"0"`) | `entries[].id` where `entries[].type == "folder"` | | Task ID | `box_file_tasks_list` or `box_task_create` response | `id` | | Task assignment ID | `box_task_assignments_list` | `entries[].id` | | Comment ID | `box_file_comments_list` | `entries[].id` | | Collaboration ID | `box_folder_collaborations_list` or `box_file_collaborations_list` | `entries[].id` | | Collection ID | `box_collections_list` | `entries[].id` (Favorites collection = type `favorites`) | | Webhook ID | `box_webhooks_list` | `entries[].id` | | User ID | `box_user_me_get` (authenticated user) or `box_users_list` | `id` | | Group ID | `box_groups_list` | `entries[].id` | | Group membership ID | `box_group_members_list` or `box_user_memberships_list` | `entries[].id` | | Web link ID | `box_folder_items_list` | `entries[].id` where `entries[].type == "web_link"` | Collaboration ID vs User ID The `collaboration_id` is different from the collaborating user’s ID. After creating a collaboration with `box_collaboration_create`, fetch the collaboration ID using `box_folder_collaborations_list` or `box_file_collaborations_list`. ## Required scopes [Section titled “Required scopes”](#required-scopes) Enable the corresponding Box app scopes before calling tools that need them: | Tools | Required scope | | ------------------------------------------------------------------------- | ------------------------------ | | All file/folder read tools, `box_file_representations_get` | `root_readonly` | | File/folder create, update, delete | `root_readwrite` | | `box_group_*`, `box_user_memberships_list` | `manage_groups` | | `box_webhook_*`, `box_webhooks_list` | `manage_webhook` | | `box_user_create`, `box_user_delete`, `box_users_list`, `box_user_update` | `manage_managed_users` | | `box_events_list` (enterprise stream) | `manage_enterprise_properties` | ## Tool list [Section titled “Tool list”](#tool-list) ### Files [Section titled “Files”](#files) ## `box_file_get` [Section titled “box\_file\_get”](#box_file_get) Retrieves detailed information about a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------------ | | `file_id` | string | Yes | ID of the file. Get it from `box_folder_items_list` on folder\_id `"0"`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_file_update` [Section titled “box\_file\_update”](#box_file_update) Updates a file’s name, description, tags, or moves it to another folder. | Name | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------- | | `file_id` | string | Yes | ID of the file to update. | | `name` | string | No | New name for the file. | | `description` | string | No | New description for the file. | | `parent_id` | string | No | ID of the folder to move the file into. | | `tags` | string | No | Comma-separated list of tags. | ## `box_file_delete` [Section titled “box\_file\_delete”](#box_file_delete) Moves a file to the trash. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `file_id` | string | Yes | ID of the file to delete. | ## `box_file_copy` [Section titled “box\_file\_copy”](#box_file_copy) Creates a copy of a file in a specified folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------------- | | `file_id` | string | Yes | ID of the file to copy. | | `parent_id` | string | Yes | ID of the destination folder. | | `name` | string | No | New name for the copied file (optional). | ## `box_file_versions_list` [Section titled “box\_file\_versions\_list”](#box_file_versions_list) Retrieves all previous versions of a file. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `file_id` | string | Yes | ID of the file. | ## `box_file_thumbnail_get` [Section titled “box\_file\_thumbnail\_get”](#box_file_thumbnail_get) Retrieves a thumbnail image for a file. | Name | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------ | | `file_id` | string | Yes | ID of the file. | | `extension` | string | Yes | Thumbnail format: `jpg` or `png`. | | `min_width` | integer | No | Minimum width of the thumbnail in pixels. | | `min_height` | integer | No | Minimum height of the thumbnail in pixels. | ## `box_file_representations_get` [Section titled “box\_file\_representations\_get”](#box_file_representations_get) Retrieves available representations for a file, such as PDFs, extracted text, or image thumbnails. Box generates representations on demand — poll until the `status` is `success` before downloading. | Name | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file. Get it from `box_folder_items_list`. | | `x_rep_hints` | string | Yes | Representation formats to request, e.g. `[pdf][extracted_text]` or `[jpg?dimensions=320x320]`. Multiple formats can be combined. | ### Folders [Section titled “Folders”](#folders) ## `box_folder_get` [Section titled “box\_folder\_get”](#box_folder_get) Retrieves a folder’s details and its immediate items. | Name | Type | Required | Description | | ----------- | ------- | -------- | ------------------------------------------------ | | `folder_id` | string | Yes | ID of the folder. Use `"0"` for the root folder. | | `fields` | string | No | Comma-separated list of fields to return. | | `sort` | string | No | Sort order: `id`, `name`, `date`, or `size`. | | `direction` | string | No | Sort direction: `ASC` or `DESC`. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max items to return (max 1000). | ## `box_folder_items_list` [Section titled “box\_folder\_items\_list”](#box_folder_items_list) Retrieves a paginated list of items in a folder. Use folder\_id `"0"` to start from the root. | Name | Type | Required | Description | | ----------- | ------- | -------- | ------------------------------------------------ | | `folder_id` | string | Yes | ID of the folder. Use `"0"` for the root folder. | | `fields` | string | No | Comma-separated list of fields to return. | | `sort` | string | No | Sort field: `id`, `name`, `date`, or `size`. | | `direction` | string | No | `ASC` or `DESC`. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max items to return (max 1000). | ## `box_folder_create` [Section titled “box\_folder\_create”](#box_folder_create) Creates a new folder inside a parent folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | -------------------------------------------- | | `name` | string | Yes | Name of the new folder. | | `parent_id` | string | Yes | ID of the parent folder. Use `"0"` for root. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_folder_update` [Section titled “box\_folder\_update”](#box_folder_update) Updates a folder’s name, description, or moves it. | Name | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------------------- | | `folder_id` | string | Yes | ID of the folder to update. | | `name` | string | No | New name for the folder. | | `description` | string | No | New description for the folder. | | `parent_id` | string | No | ID of the new parent folder to move into. | ## `box_folder_delete` [Section titled “box\_folder\_delete”](#box_folder_delete) Moves a folder to the trash. Deleting non-empty folders Pass `recursive: "true"` when deleting a folder that contains files or subfolders. Box rejects the request if the folder has contents and `recursive` is omitted. | Name | Type | Required | Description | | ----------- | ------ | -------- | -------------------------------------------------------------------- | | `folder_id` | string | Yes | ID of the folder to delete. | | `recursive` | string | No | Must be `"true"` to delete folders that contain files or subfolders. | ## `box_folder_copy` [Section titled “box\_folder\_copy”](#box_folder_copy) Creates a copy of a folder and its contents. | Name | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------ | | `folder_id` | string | Yes | ID of the folder to copy. | | `parent_id` | string | Yes | ID of the destination folder. | | `name` | string | No | New name for the copied folder (optional). | ### Search [Section titled “Search”](#search) ## `box_search` [Section titled “box\_search”](#box_search) Searches files, folders, and web links in Box. | Name | Type | Required | Description | | --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------- | | `query` | string | Yes | Search query string. | | `type` | string | No | Filter by type: `file`, `folder`, or `web_link`. | | `ancestor_folder_ids` | string | No | Comma-separated folder IDs to scope the search. | | `content_types` | string | No | Comma-separated content types: `name`, `description`, `tag`, `comments`, `file_content`. | | `file_extensions` | string | No | Comma-separated file extensions to filter (e.g. `pdf,docx`). | | `created_at_range` | string | No | ISO 8601 date range: `2024-01-01T00:00:00Z,2024-12-31T23:59:59Z`. | | `updated_at_range` | string | No | Date range for last updated. | | `owner_user_ids` | string | No | Comma-separated user IDs to filter by owner. | | `scope` | string | No | Search scope: `user_content` or `enterprise_content`. | | `limit` | integer | No | Max results (max 200). | | `offset` | integer | No | Pagination offset. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_recent_items_list` [Section titled “box\_recent\_items\_list”](#box_recent_items_list) Retrieves files and folders the user accessed recently. | Name | Type | Required | Description | | -------- | ------- | -------- | ------------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max results. | | `marker` | string | No | Pagination marker from a previous response. | ### Collaborations [Section titled “Collaborations”](#collaborations) ## `box_collaboration_create` [Section titled “box\_collaboration\_create”](#box_collaboration_create) Grants a user or group access to a file or folder. | Name | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `item_id` | string | Yes | ID of the file or folder. | | `item_type` | string | Yes | Type of item: `file` or `folder`. | | `accessible_by_id` | string | Yes | Box user or group ID to grant access to. Get user IDs from `box_users_list`. | | `accessible_by_type` | string | Yes | Type: `user` or `group`. | | `role` | string | Yes | Collaboration role: `viewer`, `previewer`, `uploader`, `previewer_uploader`, `viewer_uploader`, `co-owner`, or `editor`. | | `notify` | string | No | Notify collaborator via email (`true`/`false`). | | `can_view_path` | string | No | Allow user to see path to item (`true`/`false`). | | `expires_at` | string | No | Expiry date in ISO 8601 format. | ## `box_collaboration_get` [Section titled “box\_collaboration\_get”](#box_collaboration_get) Retrieves details of a specific collaboration. | Name | Type | Required | Description | | ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------ | | `collaboration_id` | string | Yes | ID of the collaboration. Get it from `box_folder_collaborations_list` — this is **not** the user’s ID. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_collaboration_update` [Section titled “box\_collaboration\_update”](#box_collaboration_update) Updates the role or status of a collaboration. | Name | Type | Required | Description | | ------------------ | ------- | -------- | ---------------------------------------------------------------------- | | `collaboration_id` | string | Yes | ID of the collaboration. Get it from `box_folder_collaborations_list`. | | `role` | string | No | New collaboration role. | | `status` | string | No | Collaboration status: `accepted` or `rejected`. | | `expires_at` | string | No | New expiry date in ISO 8601 format. | | `can_view_path` | boolean | No | Allow user to see path to item. | ## `box_collaboration_delete` [Section titled “box\_collaboration\_delete”](#box_collaboration_delete) Removes a collaboration, revoking user or group access. | Name | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------------------------------------------------------- | | `collaboration_id` | string | Yes | ID of the collaboration to delete. Get it from `box_folder_collaborations_list`. | ## `box_file_collaborations_list` [Section titled “box\_file\_collaborations\_list”](#box_file_collaborations_list) Retrieves all collaborations on a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_folder_collaborations_list` [Section titled “box\_folder\_collaborations\_list”](#box_folder_collaborations_list) Retrieves all collaborations on a folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | ----------------------------------------- | | `folder_id` | string | Yes | ID of the folder. | | `fields` | string | No | Comma-separated list of fields to return. | ### Comments [Section titled “Comments”](#comments) ## `box_comment_create` [Section titled “box\_comment\_create”](#box_comment_create) Adds a comment to a file. | Name | Type | Required | Description | | ---------------- | ------ | -------- | -------------------------------------------------- | | `item_id` | string | Yes | ID of the file to comment on. | | `item_type` | string | Yes | Type of item: `file` or `comment` (for replies). | | `message` | string | Yes | Text of the comment. | | `tagged_message` | string | No | Comment text with `@[user_id:user_name]` mentions. | ## `box_comment_get` [Section titled “box\_comment\_get”](#box_comment_get) Retrieves a comment. | Name | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------------------- | | `comment_id` | string | Yes | ID of the comment. Get it from `box_file_comments_list`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_comment_update` [Section titled “box\_comment\_update”](#box_comment_update) Updates the text of a comment. | Name | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------- | | `comment_id` | string | Yes | ID of the comment to update. | | `message` | string | Yes | New text for the comment. | ## `box_comment_delete` [Section titled “box\_comment\_delete”](#box_comment_delete) Removes a comment. | Name | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------- | | `comment_id` | string | Yes | ID of the comment to delete. | ## `box_file_comments_list` [Section titled “box\_file\_comments\_list”](#box_file_comments_list) Retrieves all comments on a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `fields` | string | No | Comma-separated list of fields to return. | ### Tasks [Section titled “Tasks”](#tasks) ## `box_task_create` [Section titled “box\_task\_create”](#box_task_create) Creates a task on a file. | Name | Type | Required | Description | | ----------------- | ------ | -------- | -------------------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file to attach the task to. Get it from `box_folder_items_list`. | | `message` | string | No | Task message/description. | | `action` | string | No | Action: `review` or `complete`. | | `due_at` | string | No | Due date in ISO 8601 format (e.g. `2025-12-31T00:00:00Z`). | | `completion_rule` | string | No | Completion rule: `all_assignees` or `any_assignee`. | ## `box_task_get` [Section titled “box\_task\_get”](#box_task_get) Retrieves a task’s details. | Name | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `task_id` | string | Yes | ID of the task. Get it from `box_file_tasks_list`. | ## `box_task_update` [Section titled “box\_task\_update”](#box_task_update) Updates a task’s message, due date, or completion rule. | Name | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------------------------- | | `task_id` | string | Yes | ID of the task to update. | | `message` | string | No | New message for the task. | | `due_at` | string | No | New due date in ISO 8601 format. | | `action` | string | No | New action: `review` or `complete`. | | `completion_rule` | string | No | New completion rule: `all_assignees` or `any_assignee`. | ## `box_task_delete` [Section titled “box\_task\_delete”](#box_task_delete) Removes a task from a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `task_id` | string | Yes | ID of the task to delete. | ## `box_file_tasks_list` [Section titled “box\_file\_tasks\_list”](#box_file_tasks_list) Retrieves all tasks associated with a file. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `file_id` | string | Yes | ID of the file. | ## `box_task_assignment_create` [Section titled “box\_task\_assignment\_create”](#box_task_assignment_create) Assigns a task to a user. | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------------------------------- | | `task_id` | string | Yes | ID of the task to assign. Get it from `box_file_tasks_list`. | | `user_id` | string | No | ID of the user to assign the task to. Get it from `box_users_list`. | | `user_login` | string | No | Email login of the user (alternative to `user_id`). | ## `box_task_assignment_get` [Section titled “box\_task\_assignment\_get”](#box_task_assignment_get) Retrieves a specific task assignment. | Name | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------------------------- | | `task_assignment_id` | string | Yes | ID of the task assignment. Get it from `box_task_assignments_list`. | ## `box_task_assignment_update` [Section titled “box\_task\_assignment\_update”](#box_task_assignment_update) Updates a task assignment (complete, approve, or reject). | Name | Type | Required | Description | | -------------------- | ------ | -------- | ----------------------------------------------------------------------- | | `task_assignment_id` | string | Yes | ID of the task assignment. | | `message` | string | No | Optional message/comment for the resolution. | | `resolution_state` | string | No | Resolution state: `completed`, `incomplete`, `approved`, or `rejected`. | Completed tasks Box returns a `403` error when you try to delete an assignment on a completed task. This is expected API behavior — only delete assignments on tasks with `incomplete` status. ## `box_task_assignment_delete` [Section titled “box\_task\_assignment\_delete”](#box_task_assignment_delete) Removes a task assignment from a user. | Name | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------ | | `task_assignment_id` | string | Yes | ID of the task assignment to remove. | ## `box_task_assignments_list` [Section titled “box\_task\_assignments\_list”](#box_task_assignments_list) Retrieves all assignments for a task. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `task_id` | string | Yes | ID of the task. | ### Shared links [Section titled “Shared links”](#shared-links) ## `box_shared_link_file_create` [Section titled “box\_shared\_link\_file\_create”](#box_shared_link_file_create) Creates or updates a shared link for a file. | Name | Type | Required | Description | | -------------- | ------- | -------- | ---------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `access` | string | No | Shared link access level: `open`, `company`, or `collaborators`. | | `unshared_at` | string | No | Expiry date in ISO 8601 format. | | `password` | string | No | Password to protect the shared link. | | `can_download` | boolean | No | Allow download (`true`/`false`). | | `can_preview` | boolean | No | Allow preview (`true`/`false`). | ## `box_shared_link_folder_create` [Section titled “box\_shared\_link\_folder\_create”](#box_shared_link_folder_create) Creates or updates a shared link for a folder. | Name | Type | Required | Description | | -------------- | ------- | -------- | ---------------------------------------------------------------- | | `folder_id` | string | Yes | ID of the folder. | | `access` | string | No | Shared link access level: `open`, `company`, or `collaborators`. | | `unshared_at` | string | No | Expiry date in ISO 8601 format. | | `password` | string | No | Password to protect the shared link. | | `can_download` | boolean | No | Allow download (`true`/`false`). | ### Collections [Section titled “Collections”](#collections) ## `box_collections_list` [Section titled “box\_collections\_list”](#box_collections_list) Retrieves all collections for the user (e.g. Favorites). | Name | Type | Required | Description | | -------- | ------- | -------- | ----------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max results. | ## `box_collection_items_list` [Section titled “box\_collection\_items\_list”](#box_collection_items_list) Retrieves the items in a collection. Use `box_collections_list` first to get the collection ID. | Name | Type | Required | Description | | --------------- | ------- | -------- | --------------------------------------------------------- | | `collection_id` | string | Yes | ID of the collection. Get it from `box_collections_list`. | | `fields` | string | No | Comma-separated list of fields to return. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max results. | ### Metadata [Section titled “Metadata”](#metadata) ## `box_file_metadata_create` [Section titled “box\_file\_metadata\_create”](#box_file_metadata_create) Applies metadata to a file using a metadata template. Requires an enterprise metadata template. | Name | Type | Required | Description | | -------------- | ------ | -------- | ---------------------------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `scope` | string | Yes | Template scope: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. Get it from `box_metadata_templates_list`. | | `data_json` | string | Yes | JSON string of metadata fields and values, e.g. `"{\"department\": \"Finance\"}"`. | ## `box_file_metadata_get` [Section titled “box\_file\_metadata\_get”](#box_file_metadata_get) Retrieves a specific metadata instance on a file. | Name | Type | Required | Description | | -------------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `scope` | string | Yes | Template scope: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. | ## `box_file_metadata_list` [Section titled “box\_file\_metadata\_list”](#box_file_metadata_list) Retrieves all metadata instances attached to a file. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `file_id` | string | Yes | ID of the file. | ## `box_file_metadata_delete` [Section titled “box\_file\_metadata\_delete”](#box_file_metadata_delete) Removes a metadata instance from a file. | Name | Type | Required | Description | | -------------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `scope` | string | Yes | Template scope: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. | ## `box_folder_metadata_list` [Section titled “box\_folder\_metadata\_list”](#box_folder_metadata_list) Retrieves all metadata instances on a folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | ----------------- | | `folder_id` | string | Yes | ID of the folder. | ## `box_metadata_template_get` [Section titled “box\_metadata\_template\_get”](#box_metadata_template_get) Retrieves a metadata template schema. Returns `404` if no enterprise templates exist. | Name | Type | Required | Description | | -------------- | ------ | -------- | ------------------------------------------------ | | `scope` | string | Yes | Scope of the template: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. | ## `box_metadata_templates_list` [Section titled “box\_metadata\_templates\_list”](#box_metadata_templates_list) Retrieves all metadata templates for the enterprise. | Name | Type | Required | Description | | -------- | ------- | -------- | ------------------ | | `marker` | string | No | Pagination marker. | | `limit` | integer | No | Max results. | ### Web links [Section titled “Web links”](#web-links) ## `box_web_link_create` [Section titled “box\_web\_link\_create”](#box_web_link_create) Creates a web link (bookmark) inside a folder. | Name | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------------- | | `url` | string | Yes | URL of the web link. | | `parent_id` | string | Yes | ID of the parent folder. Use `"0"` for root. | | `name` | string | No | Name for the web link. | | `description` | string | No | Description of the web link. | ## `box_web_link_get` [Section titled “box\_web\_link\_get”](#box_web_link_get) Retrieves a web link’s details. | Name | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------------------- | | `web_link_id` | string | Yes | ID of the web link. Get it from `box_folder_items_list` (type: `web_link`). | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_web_link_update` [Section titled “box\_web\_link\_update”](#box_web_link_update) Updates a web link’s URL, name, or description. | Name | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------- | | `web_link_id` | string | Yes | ID of the web link to update. | | `url` | string | No | New URL. | | `name` | string | No | New name. | | `description` | string | No | New description. | | `parent_id` | string | No | New parent folder ID. | ## `box_web_link_delete` [Section titled “box\_web\_link\_delete”](#box_web_link_delete) Removes a web link. | Name | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------- | | `web_link_id` | string | Yes | ID of the web link to delete. | ### Trash [Section titled “Trash”](#trash) ## `box_trash_list` [Section titled “box\_trash\_list”](#box_trash_list) Retrieves items in the user’s trash. | Name | Type | Required | Description | | ----------- | ------- | -------- | ----------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | | `sort` | string | No | Sort field: `name`, `date`, or `size`. | | `direction` | string | No | Sort direction: `ASC` or `DESC`. | ## `box_trash_file_restore` [Section titled “box\_trash\_file\_restore”](#box_trash_file_restore) Restores a file from the trash. | Name | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------- | | `file_id` | string | Yes | ID of the trashed file. | | `name` | string | No | New name if the original name is already taken. | | `parent_id` | string | No | Parent folder ID if the original location is unavailable. | ## `box_trash_file_permanently_delete` [Section titled “box\_trash\_file\_permanently\_delete”](#box_trash_file_permanently_delete) Permanently deletes a trashed file. This action cannot be undone. | Name | Type | Required | Description | | --------- | ------ | -------- | ----------------------- | | `file_id` | string | Yes | ID of the trashed file. | ## `box_trash_folder_restore` [Section titled “box\_trash\_folder\_restore”](#box_trash_folder_restore) Restores a folder from the trash. | Name | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------------------------- | | `folder_id` | string | Yes | ID of the trashed folder. | | `name` | string | No | New name if the original is already taken. | | `parent_id` | string | No | New parent folder ID if the original is unavailable. | ## `box_trash_folder_permanently_delete` [Section titled “box\_trash\_folder\_permanently\_delete”](#box_trash_folder_permanently_delete) Permanently deletes a trashed folder. This action cannot be undone. | Name | Type | Required | Description | | ----------- | ------ | -------- | ------------------------- | | `folder_id` | string | Yes | ID of the trashed folder. | ### Webhooks [Section titled “Webhooks”](#webhooks) Webhooks require the `manage_webhook` scope. ## `box_webhook_create` [Section titled “box\_webhook\_create”](#box_webhook_create) Creates a webhook to receive event notifications when something changes in a file or folder. | Name | Type | Required | Description | | ------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `target_id` | string | Yes | ID of the file or folder to watch. | | `target_type` | string | Yes | Type of target: `file` or `folder`. | | `address` | string | Yes | HTTPS URL to receive webhook notifications. Must be publicly accessible. | | `triggers` | array | Yes | Array of event strings, e.g. `["FILE.UPLOADED","FILE.DELETED"]`. See [Box webhook triggers](https://developer.box.com/reference/resources/webhook/) for the full list. | ## `box_webhook_get` [Section titled “box\_webhook\_get”](#box_webhook_get) Retrieves a webhook’s details. | Name | Type | Required | Description | | ------------ | ------ | -------- | --------------------------------------------------- | | `webhook_id` | string | Yes | ID of the webhook. Get it from `box_webhooks_list`. | ## `box_webhook_update` [Section titled “box\_webhook\_update”](#box_webhook_update) Updates a webhook’s address or triggers. | Name | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------ | | `webhook_id` | string | Yes | ID of the webhook to update. | | `address` | string | No | New HTTPS URL for notifications. | | `triggers` | array | No | New array of event strings. | | `target_id` | string | No | New target ID. | | `target_type` | string | No | New target type: `file` or `folder`. | ## `box_webhook_delete` [Section titled “box\_webhook\_delete”](#box_webhook_delete) Removes a webhook. | Name | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------- | | `webhook_id` | string | Yes | ID of the webhook to delete. | ## `box_webhooks_list` [Section titled “box\_webhooks\_list”](#box_webhooks_list) Retrieves all webhooks for the application. | Name | Type | Required | Description | | -------- | ------- | -------- | ------------------ | | `marker` | string | No | Pagination marker. | | `limit` | integer | No | Max results. | ### Users [Section titled “Users”](#users) User management tools require the `manage_managed_users` scope. Users created with Box must use an email address within the enterprise’s verified domain. ## `box_user_me_get` [Section titled “box\_user\_me\_get”](#box_user_me_get) Retrieves information about the currently authenticated user. No parameters required — use this to get your own user ID. | Name | Type | Required | Description | | -------- | ------ | -------- | ----------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_user_get` [Section titled “box\_user\_get”](#box_user_get) Retrieves information about a specific user. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------ | | `user_id` | string | Yes | ID of the user. Get it from `box_users_list` or `box_user_me_get`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_users_list` [Section titled “box\_users\_list”](#box_users_list) Retrieves all users in the enterprise. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------ | | `filter_term` | string | No | Filter users by name or login. | | `user_type` | string | No | Filter by type: `all`, `managed`, or `external`. | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max users to return. | | `offset` | integer | No | Pagination offset. | ## `box_user_create` [Section titled “box\_user\_create”](#box_user_create) Creates a new managed user in the enterprise. | Name | Type | Required | Description | | ------------------------- | ------- | -------- | ------------------------------------------------------------------------------ | | `name` | string | Yes | Full name of the user. | | `login` | string | No | Email address (login) for managed users. Must be within the enterprise domain. | | `role` | string | No | User role: `user` or `coadmin`. | | `space_amount` | integer | No | Storage quota in bytes (`-1` for unlimited). | | `is_platform_access_only` | boolean | No | Set `true` for app users (no login required). | ## `box_user_update` [Section titled “box\_user\_update”](#box_user_update) Updates a user’s properties in the enterprise. | Name | Type | Required | Description | | ---------------- | ------- | -------- | ---------------------------------------------------------- | | `user_id` | string | Yes | ID of the user to update. | | `name` | string | No | New full name. | | `role` | string | No | New role: `user` or `coadmin`. | | `status` | string | No | New status: `active`, `inactive`, or `cannot_delete_edit`. | | `space_amount` | integer | No | Storage quota in bytes. | | `tracking_codes` | string | No | Tracking codes as a JSON array string. | ## `box_user_delete` [Section titled “box\_user\_delete”](#box_user_delete) Removes a user from the enterprise. | Name | Type | Required | Description | | --------- | ------ | -------- | ---------------------------------------------------------- | | `user_id` | string | Yes | ID of the user to delete. | | `notify` | string | No | Notify user via email (`true`/`false`). | | `force` | string | No | Force deletion even if user owns content (`true`/`false`). | ## `box_user_memberships_list` [Section titled “box\_user\_memberships\_list”](#box_user_memberships_list) Retrieves all group memberships for a user. | Name | Type | Required | Description | | --------- | ------- | -------- | ------------------ | | `user_id` | string | Yes | ID of the user. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | ### Groups [Section titled “Groups”](#groups) Group tools require the `manage_groups` scope. ## `box_groups_list` [Section titled “box\_groups\_list”](#box_groups_list) Retrieves all groups in the enterprise. | Name | Type | Required | Description | | ------------- | ------- | -------- | ----------------------------------------- | | `filter_term` | string | No | Filter groups by name. | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | ## `box_group_create` [Section titled “box\_group\_create”](#box_group_create) Creates a new group in the enterprise. | Name | Type | Required | Description | | -------------------------- | ------ | -------- | ---------------------------------------------------------------------------------------- | | `name` | string | Yes | Name of the group. | | `description` | string | No | Description of the group. | | `provenance` | string | No | Identifier to distinguish manually created vs synced groups. | | `invitability_level` | string | No | Who can invite to group: `admins_only`, `admins_and_members`, or `all_managed_users`. | | `member_viewability_level` | string | No | Who can view group members: `admins_only`, `admins_and_members`, or `all_managed_users`. | ## `box_group_get` [Section titled “box\_group\_get”](#box_group_get) Retrieves information about a group. | Name | Type | Required | Description | | ---------- | ------ | -------- | ----------------------------------------------- | | `group_id` | string | Yes | ID of the group. Get it from `box_groups_list`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_group_update` [Section titled “box\_group\_update”](#box_group_update) Updates a group’s properties. | Name | Type | Required | Description | | -------------------------- | ------ | -------- | ---------------------------------------------------------------------------- | | `group_id` | string | Yes | ID of the group to update. | | `name` | string | No | New name for the group. | | `description` | string | No | New description. | | `invitability_level` | string | No | Who can invite: `admins_only`, `admins_and_members`, or `all_managed_users`. | | `member_viewability_level` | string | No | Who can view members. | ## `box_group_delete` [Section titled “box\_group\_delete”](#box_group_delete) Permanently deletes a group. | Name | Type | Required | Description | | ---------- | ------ | -------- | -------------------------- | | `group_id` | string | Yes | ID of the group to delete. | ## `box_group_members_list` [Section titled “box\_group\_members\_list”](#box_group_members_list) Retrieves all members of a group. | Name | Type | Required | Description | | ---------- | ------- | -------- | ------------------ | | `group_id` | string | Yes | ID of the group. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | ## `box_group_membership_add` [Section titled “box\_group\_membership\_add”](#box_group_membership_add) Adds a user to a group. | Name | Type | Required | Description | | ---------- | ------ | -------- | ---------------------------------------------------- | | `user_id` | string | Yes | ID of the user to add. Get it from `box_users_list`. | | `group_id` | string | Yes | ID of the group. | | `role` | string | No | Role in the group: `member` or `admin`. | ## `box_group_membership_get` [Section titled “box\_group\_membership\_get”](#box_group_membership_get) Retrieves a specific group membership. | Name | Type | Required | Description | | --------------------- | ------ | -------- | ----------------------------------------------------------------- | | `group_membership_id` | string | Yes | ID of the group membership. Get it from `box_group_members_list`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_group_membership_update` [Section titled “box\_group\_membership\_update”](#box_group_membership_update) Updates a user’s role in a group. | Name | Type | Required | Description | | --------------------- | ------ | -------- | ------------------------------- | | `group_membership_id` | string | Yes | ID of the membership to update. | | `role` | string | No | New role: `member` or `admin`. | ## `box_group_membership_remove` [Section titled “box\_group\_membership\_remove”](#box_group_membership_remove) Removes a user from a group. | Name | Type | Required | Description | | --------------------- | ------ | -------- | --------------------------------------------------------------------------- | | `group_membership_id` | string | Yes | ID of the group membership to remove. Get it from `box_group_members_list`. | ### Events [Section titled “Events”](#events) ## `box_events_list` [Section titled “box\_events\_list”](#box_events_list) Retrieves events from the Box event stream. Use `admin_logs` for enterprise-wide events (requires `manage_enterprise_properties` scope). | Name | Type | Required | Description | | ----------------- | ------- | -------- | ------------------------------------------------------------- | | `stream_type` | string | No | Event stream type: `all`, `changes`, `sync`, or `admin_logs`. | | `stream_position` | string | No | Pagination position from a previous response. | | `limit` | integer | No | Max events to return. | | `event_type` | string | No | Comma-separated list of event types to filter. | | `created_after` | string | No | Return events after this date (ISO 8601). | | `created_before` | string | No | Return events before this date (ISO 8601). | --- # DOCUMENT BOUNDARY --- # Glossary > A comprehensive glossary of terms related to authentication, authorization, and identity management in B2B SaaS applications. ## Access Token [Section titled “Access Token”](#access-token) * **Definition**: A credential (often a JWT) issued by the authorization server that the client uses to access the resource server. It represents the client’s authorization and typically has an expiry time and scopes attached. The resource server validates this token. ## Administrator [Section titled “Administrator”](#administrator) * **Definition**: An IT administrator responsible for managing identity provider configurations within a customer organization. ## Admin Portal [Section titled “Admin Portal”](#admin-portal) * **Definition**: A customizable web interface for customers’ IT administrators to manage identity provider configurations. ## AI Agent Identity and Attestation [Section titled “AI Agent Identity and Attestation”](#ai-agent-identity-and-attestation) * **Definition**: A process by which an AI agent proves its identity to an authorization server, often using cryptographic evidence (e.g. signed JWT assertions or hardware-backed keys), so the server can trust requests coming from that agent. ## API Endpoint [Section titled “API Endpoint”](#api-endpoint) * **Definition**: A specific URL where an API can be accessed to perform specific operations or retrieve data. ## API Key [Section titled “API Key”](#api-key) * **Definition**: A unique identifier used to authenticate API requests to Scalekit, allowing secure access to the platform’s features and services. ## App [Section titled “App”](#app) * **Definition**: Another term for an application, representing the software product or service sold to customers. ## Application [Section titled “Application”](#application) * **Definition**: The software product or service offered by B2B App developers to customers. * **Example**: A workspace can contain multiple applications. ## Audit Log [Section titled “Audit Log”](#audit-log) * **Definition**: A record of all activities and changes made within the B2B App, used for security and compliance purposes. ## Authentication [Section titled “Authentication”](#authentication) * **Definition**: The process of verifying the identity of a user or system attempting to access the B2B App. ## Authorization [Section titled “Authorization”](#authorization) * **Definition**: The process of determining what actions or resources a user is allowed to access within the B2B App. ## Authorization Server [Section titled “Authorization Server”](#authorization-server) * **Definition**: The server in OAuth that authenticates clients and issues tokens (could be a part of your SaaS or a third-party IdP like Okta Azure AD, etc.). It essentially says “Yes, client X, here is a token proving you are authenticated and allowed to do Y.” ## Authorization URL [Section titled “Authorization URL”](#authorization-url) * **Definition**: The URL to which users are redirected to grant authorization for the B2B App. ## B2B App [Section titled “B2B App”](#b2b-app) * **Definition**: An application designed for use by other businesses or organizations to streamline operations. ## B2B SaaS App [Section titled “B2B SaaS App”](#b2b-saas-app) * **Definition**: A type of B2B App delivered over the internet, allowing access without local installation. ## Claims [Section titled “Claims”](#claims) * **Definition**: Information about a user that is passed from an identity provider to a service provider during authentication. ## Client Credentials Flow [Section titled “Client Credentials Flow”](#client-credentials-flow) * **Definition**: The OAuth process where a machine client exchanges its client ID and secret for an access token from the auth server. No user involved. The resulting token represents the machine and carries scopes for what it can do. ## Configuration [Section titled “Configuration”](#configuration) * **Definition**: The settings and parameters that define how the B2B App interacts with Scalekit and other services. ## Connection [Section titled “Connection”](#connection) * **Definition**: A link between the B2B App and a customer’s identity provider for enabling Single Sign-On (SSO). * **Example**: Each organization can have its own unique connection. ## Customer [Section titled “Customer”](#customer) * **Definition**: A business or organization that uses the application to meet specific needs. ## Custom Attribute [Section titled “Custom Attribute”](#custom-attribute) * **Definition**: Additional fields added to user data in Scalekit for storing extra information. ## Dashboard [Section titled “Dashboard”](#dashboard) * **Definition**: The main control panel within Scalekit for configuring settings, viewing analytics, and managing integrations. ## Deprovisioning [Section titled “Deprovisioning”](#deprovisioning) * **Definition**: The process of removing user access and accounts when they are no longer needed or authorized. ## Directory Provider [Section titled “Directory Provider”](#directory-provider) * **Definition**: An organization offering directory services, including identity providers. ## Directory Sync [Section titled “Directory Sync”](#directory-sync) * **Definition**: A module in Scalekit for automatic provisioning and deprovisioning of user accounts. ## Documentation [Section titled “Documentation”](#documentation) * **Definition**: Comprehensive guides and references that explain how to use and integrate with Scalekit’s features and services. ## Dynamic Client Registration [Section titled “Dynamic Client Registration”](#dynamic-client-registration) * **Definition**: A protocol (RFC 7591) that allows a client application to programmatically register itself with an authorization server to obtain credentials (client ID/secret, etc.). Useful for large-scale or third-party ecosystems where manual registration of clients is not feasible or to enable self-service integration in a controlled way. ## Environment [Section titled “Environment”](#environment) * **Definition**: Different versions or instances of an application, such as test and live environments. * **Example**: Each environment has its own settings and is isolated for security. ## Error Handling [Section titled “Error Handling”](#error-handling) * **Definition**: The process of managing and responding to errors that occur during API calls or application operations. ## Federation [Section titled “Federation”](#federation) * **Definition**: The process of establishing trust between different identity providers and service providers for seamless authentication. ## ID Token [Section titled “ID Token”](#id-token) * **Definition**: A JSON Web Token (JWT) issued by the identity provider containing user identity information. ## Identity Provider (IdP) [Section titled “Identity Provider (IdP)”](#identity-provider-idp) * **Definition**: A service that verifies user identity and provides information about user attributes. ## IdP Simulator [Section titled “IdP Simulator”](#idp-simulator) * **Definition**: A tool that mimics the behavior of an identity provider for testing integrations. ## Integration [Section titled “Integration”](#integration) * **Definition**: The process of connecting Scalekit with other systems or services to enable seamless data flow and functionality. ## JWT [Section titled “JWT”](#jwt) * **Definition**: A standard format for representing claims securely between two parties. It is a compact, URL-safe means of representing claims securely between two parties. ## Logout [Section titled “Logout”](#logout) * **Definition**: The process of ending a user’s session and revoking their access to the B2B App. ## Machine-to-Machine (M2M) Authentication [Section titled “Machine-to-Machine (M2M) Authentication”](#machine-to-machine-m2m-authentication) * **Definition**: Methods for verifying identity between two automated services or software entities without human intervention. Ensures a client program (machine) is trusted by the service it calls, typically via tokens, keys, or certificates. ## MFA (Multi-Factor Authentication) [Section titled “MFA (Multi-Factor Authentication)”](#mfa-multi-factor-authentication) * **Definition**: A security feature that requires users to provide multiple forms of verification before accessing the B2B App. ## Model Context Protocol (MCP) [Section titled “Model Context Protocol (MCP)”](#model-context-protocol-mcp) * **Definition**: A new protocol (spearheaded by Anthropic and others) to standardize how AI models (assistants) can interact with external tools and data. It defines how AI agents can discover available “tools” (APIs) and the context to call them. For auth, MCP leverages OAuth 2.1 – effectively requiring AI agents to go through a secure authorization process to get access to those tools. Think of it as an evolving standard to make AI to SaaS integrations plug-and-play, with security built-in via OAuth. ## Mutual TLS (mTLS) [Section titled “Mutual TLS (mTLS)”](#mutual-tls-mtls) * **Definition**: A transport layer security mechanism where *both client and server present certificates* to mutually authenticate each other during the TLS handshake. Provides strong assurance of identities at connection level and encrypts the traffic. Used in high-security environments and internal service-to-service auth. ## Normalized Payload [Section titled “Normalized Payload”](#normalized-payload) * **Definition**: A standardized format for data sent from Scalekit to the B2B App. ## OAuth [Section titled “OAuth”](#oauth) * **Definition**: A standard protocol for authorization enabling limited access to user data. ## OAuth 2.0/OAuth 2.1 [Section titled “OAuth 2.0/OAuth 2.1”](#oauth-20oauth-21) * **Definition**: An authorization framework widely used for granting access to resources. OAuth 2.0 defines various *flows* (grant types) for different scenarios (authorization code, client credentials, etc.). OAuth 2.1 is an incremental update that compiles security best practices (PKCE required, no legacy flows, etc.). In M2M context, OAuth’s **Client Credentials Grant** is most relevant, allowing a service to get an access token using its own credentials. ## OAuth 2.0 Token Exchange (RFC 8693) [Section titled “OAuth 2.0 Token Exchange (RFC 8693)”](#oauth-20-token-exchange-rfc-8693) * **Definition**: A protocol that lets one token be exchanged for another—for example, an AI agent exchanging its machine-client token for a token scoped to call a downstream service on behalf of a user or another service. Enables delegation and impersonation scenarios. ## OIDC [Section titled “OIDC”](#oidc) * **Definition**: A standard protocol for authentication that builds on OAuth 2.0. ## OpenID Connect (OIDC) [Section titled “OpenID Connect (OIDC)”](#openid-connect-oidc) * **Definition**: An identity layer on top of OAuth 2.0 (often used for user authentication). Mentioned here because the discovery document and id\_token concepts come from OIDC. OIDC isn’t directly about M2M auth (it’s user-centric), but the OIDC discovery (`.well-known`) and JWT usage are leveraged in service auth too. ## Organization [Section titled “Organization”](#organization) * **Definition**: The customers of B2B Apps, typically businesses. * **Example**: Each business is considered an organization with its own users. ## PKCE (Proof Key for Code Exchange) [Section titled “PKCE (Proof Key for Code Exchange)”](#pkce-proof-key-for-code-exchange) * **Definition**: An extension to OAuth used to prevent interception of authorization codes. The client generates a random secret (code verifier) and sends a hashed version (code challenge) in the auth request, then must present the original secret when redeeming the code. Ensures that even if an attacker intercepts the auth code, they can’t exchange it without the secret. PKCE is now recommended for any OAuth client that can’t secure a client secret – including mobile, SPA, and some machine clients. ## PKI (Public Key Infrastructure) [Section titled “PKI (Public Key Infrastructure)”](#pki-public-key-infrastructure) * **Definition**: The system of certificate authorities, processes, and tools for managing digital certificates (like those used in mTLS). Involves issuing certs, distributing them, rotating when expired, revoking if compromised, etc. A robust PKI is needed to effectively use certificate-based auth at scale. ## Provisioning [Section titled “Provisioning”](#provisioning) * **Definition**: The process of creating and managing user accounts and access rights in the B2B App. ## Rate Limiting [Section titled “Rate Limiting”](#rate-limiting) * **Definition**: A mechanism that controls the rate of requests a user or application can make to the API within a specific time period. ## Refresh Token [Section titled “Refresh Token”](#refresh-token) * **Definition**: A long-lived token that can be used to get new access tokens without re-authenticating. In M2M auth, refresh tokens are rarely used because the client can just use its credentials again. Refresh tokens are more for user-based flows to avoid prompting the user frequently. ## Resource Server [Section titled “Resource Server”](#resource-server) * **Definition**: The API or service that the client wants to use – it receives tokens from clients and decides whether to accept them (by validating them). In our context, your SaaS API is a resource server that expects a valid token for requests. ## Role-Based Access Control (RBAC) [Section titled “Role-Based Access Control (RBAC)”](#role-based-access-control-rbac) * **Definition**: A method of regulating access to resources based on the roles of individual users within an organization. ## SAML Assertion [Section titled “SAML Assertion”](#saml-assertion) * **Definition**: A statement by an identity provider indicating a user’s authentication status. ## SCIM [Section titled “SCIM”](#scim) * **Definition**: SCIM (System for Cross-domain Identity Management) is a standard protocol for automating the provisioning and deprovisioning of user accounts and their attributes between an identity provider and a service provider. ## Scopes [Section titled “Scopes”](#scopes) * **Definition**: Strings that define what access is being requested or granted in an OAuth token. For example, `read:inventory` or `payments:create`. Scopes let the token carry permissions, enabling the resource server to allow or deny requests based on scope. Principle of least privilege is implemented by granting minimal scopes. ## Service Account [Section titled “Service Account”](#service-account) * **Definition**: A non-human account used by a software service. In context, it’s an identity set up for a machine to use. For example, a service account could be created for “Data Sync Service” in a customer’s tenant on your app. Service accounts have credentials (like client ID/secret or keys) to authenticate, and usually have roles or scopes assigned just like a user would. They enable organization-level or service-level tokens without tying to an actual person. ## Service Provider [Section titled “Service Provider”](#service-provider) * **Definition**: An entity offering a product or service to another organization or individual, especially in SSO contexts. ## Session [Section titled “Session”](#session) * **Definition**: A period of interaction between a user and the B2B App, typically starting with authentication and ending with logout. ## Social Connection [Section titled “Social Connection”](#social-connection) * **Definition**: Allows users to sign in using their social media accounts. ## SSO (Single Sign-On) [Section titled “SSO (Single Sign-On)”](#sso-single-sign-on) * **Definition**: An authentication method that allows users to access multiple applications with a single set of credentials. ## Team Member [Section titled “Team Member”](#team-member) * **Definition**: Individuals from the B2B App developer’s company who use Scalekit to manage applications. * **Roles**: Can include developers, product managers, or customer support staff. ## Tenant [Section titled “Tenant”](#tenant) * **Definition**: An isolated instance of the B2B App for a specific customer organization, with its own data and configurations. ## Token [Section titled “Token”](#token) * **Definition**: A piece of data that represents a user’s authentication status and permissions, used for accessing protected resources. ## User [Section titled “User”](#user) * **Definition**: An individual who uses the B2B App, typically belonging to a customer organization. ## User Attribute [Section titled “User Attribute”](#user-attribute) * **Definition**: Properties describing a user’s identity, used for authentication and access control. ## Webhook [Section titled “Webhook”](#webhook) * **Definition**: A mechanism for the B2B App to receive notifications or updates from Scalekit. ## Webhook Payload [Section titled “Webhook Payload”](#webhook-payload) * **Definition**: The data sent by Scalekit to the B2B App when a webhook is triggered, containing information about the event. ## Workspace [Section titled “Workspace”](#workspace) * **Definition**: A centralized hub for B2B App developers to manage applications and settings. * **Example**: Think of it as a command center for efficient application management. ## Zero Trust Security [Section titled “Zero Trust Security”](#zero-trust-security) * **Definition**: A security model where no user or device is inherently trusted, even if inside the network. Every access request must be authenticated, authorized, and continuously validated. For M2M, this means authenticating every service communication, minimizing implicit trust, and verifying identities at multiple layers (network & application). It often involves micro-segmentation and strict identity and access management for every machine identity. --- # DOCUMENT BOUNDARY --- # Interceptor triggers > The points in the authentication flow where Scalekit calls your interceptor endpoint ## `PRE_SIGNUP` [Section titled “PRE\_SIGNUP”](#pre_signup) Fires before a user creates a new organization. Use this to validate email domains, check against blocklists, or enforce custom signup policies. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit) PRE\_SIGNUP — request body ```json 1 { 2 "display_name": "Validate email domain", 3 "trigger_point": "PRE_SIGNUP", 4 "interceptor_context": { 5 "environment_id": "env_92561807201272162", 6 "user_id": "usr_93418238346728951", // Present only if user exists in another organization 7 "user_email": "john.doe@acmecorp.com", // Email attempting to sign up 8 "connection_details": [ 9 { 10 "id": "conn_92561808744978132", 11 "type": "OAUTH", // OAUTH, SAML, OIDC, or PASSWORDLESS 12 "provider": "GOOGLE" // Identity provider used for authentication 13 } 14 ], 15 //Contains parameters from the /oauth/authorize request 16 "auth_request": { 17 "connection_id": "conn_81665025441299343", 18 "organization_id": "org_102953846317318346", 19 "domain": "foocorp.com", 20 "login_hint": "john.doe@example.com", 21 "state": "xsrPHl7k7ARgdhC6" 22 }, 23 "device_type": "Desktop", // Desktop, Mobile, Tablet, or Unknown 24 "ip_address": "203.0.113.24", // Client's IP address for geolocation or blocklist checks 25 "region": "IN", // Two-letter country code 26 "city": "Bengaluru", 27 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...", 28 "triggered_at": "2025-10-09T09:48:02.875Z" // ISO 8601 timestamp 29 }, 30 "data": { 31 // User object present only when user already exists in another organization 32 "user": { 33 "id": "usr_93418238346728951", 34 "name": "John Doe", 35 "email": "john.doe@acmecorp.com", 36 "email_verified": true, 37 "created_at": "2025-10-06T11:06:49.120Z", 38 "updated_at": "2025-10-06T13:33:06.479Z", 39 "given_name": "John", 40 "family_name": "Doe", 41 "metadata": { 42 "type": "social_user" 43 }, 44 "memberships": [ // Existing organization memberships 45 { 46 "organization_id": "org_93418204671239864", 47 "status": "ACTIVE", 48 "roles": [ 49 "admin" 50 ], 51 "metadata": { 52 "cost": { 53 "category": "platform", 54 "region": "US" 55 }, 56 "department": "engineering" 57 }, 58 "organization_name": "Example inc" 59 } 60 ] 61 } 62 } 63 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return) PRE\_SIGNUP — response body ```json 1 { 2 // Required: choose ALLOW or DENY 3 "decision": "DENY", // ALLOW | DENY 4 // Optional with DENY 5 "error": { 6 "message": "Only @acmecorp.com email addresses are allowed to sign up" // Shown to user when DENY 7 }, 8 // Optional with ALLOW, Include when the user is to be provisioned in an existing organization. 9 "response": { 10 "create_organization_membership": { 11 // either external_organization_id or organization_id is required 12 "external_organization_id": "ext_B6YycAGRaPmnuxAFPT5KI4HBHxr4qWX", 13 "organization_id": "org_102953846317318346", 14 "roles": [ 15 "admin", 16 "viewer" 17 ] 18 } 19 } 20 } ``` ## `PRE_SESSION_CREATION` [Section titled “PRE\_SESSION\_CREATION”](#pre_session_creation) Fires before session tokens are issued for a user. Use this to add custom claims to the access token, apply conditional access policies, or integrate with external authorization systems. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit-1) PRE\_SESSION\_CREATION — request body ```json 1 { 2 "display_name": "Add custom claims to tokens", 3 "trigger_point": "PRE_SESSION_CREATION", 4 "interceptor_context": { 5 "environment_id": "env_92561807204567213", 6 "user_id": "usr_93418238346728951", 7 "user_email": "john.doe@acmecorp.com", 8 "organization_id": "org_93418204671239864", // Organization user is logging into 9 "connection_details": [ 10 { 11 "id": "conn_92561808744978132", 12 "type": "OAUTH", // Authentication method used 13 "provider": "GOOGLE" 14 } 15 ], 16 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...", 17 "device_type": "Desktop", // Desktop, Mobile, Tablet, or Unknown 18 "ip_address": "203.0.113.24", // Use for conditional access based on location 19 "region": "US", // Two-letter country code 20 "city": "San Francisco", 21 "triggered_at": "2025-10-08T15:22:42.381Z" // ISO 8601 timestamp 22 }, 23 "data": { 24 "user": { 25 "id": "usr_93418238346728951", 26 "name": "John Doe", 27 "email": "john.doe@acmecorp.com", 28 "email_verified": true, 29 "created_at": "2025-10-06T11:06:49.120Z", 30 "updated_at": "2025-10-06T13:33:06.479Z", 31 "first_name": "John", 32 "last_name": "Doe", 33 "memberships": [ // All organizations this user belongs to 34 { 35 "organization_id": "org_93418204671239864", 36 "status": "ACTIVE" 37 } 38 ] 39 } 40 } 41 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return-1) PRE\_SESSION\_CREATION — response body ```json 1 { 2 "decision": "ALLOW", // Required: ALLOW to issue tokens, DENY to block login 3 "response": { 4 "claims": { // Optional: Custom claims added to the access token (under `custom_claims`) 5 "subscription_tier": "enterprise", 6 "data_region": "us-west-2", 7 "feature_flags": ["analytics_dashboard", "api_access", "custom_branding"], 8 "account_manager": "jane.smith@acmecorp.com" 9 } 10 } 11 } ``` ## `PRE_USER_INVITATION` [Section titled “PRE\_USER\_INVITATION”](#pre_user_invitation) Fires before an invitation is created or sent for a new organization member. Use this to validate invitee email addresses, enforce invitation policies, or check user limits. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit-2) PRE\_USER\_INVITATION — request body ```json 1 { 2 "display_name": "Validate invitation policy", 3 "trigger_point": "PRE_USER_INVITATION", 4 "interceptor_context": { 5 "environment_id": "env_92561807201272162", 6 "user_id": "usr_93418238346728951", // Present only if invitee already exists in another org 7 "user_email": "sarah.johnson@contractor.com", // Email address being invited 8 "organization_id": "org_93731871904672153", // Organization sending the invitation 9 "city": "Bengaluru", 10 "device_type": "Desktop", // Device of the person sending the invitation 11 "ip_address": "182.156.5.2", // IP of the person sending the invitation 12 "region": "IN", // Two-letter country code 13 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...", 14 "triggered_at": "2025-10-09T12:50:41.803Z" // ISO 8601 timestamp 15 }, 16 "data": { 17 "organization": { // Organization details for context 18 "id": "org_93731871904672153", 19 "name": "Acme Corp" 20 } 21 } 22 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return-2) PRE\_USER\_INVITATION — response body ```json 1 { 2 "decision": "DENY", // Required: ALLOW to send invitation, DENY to block 3 "error": { 4 "message": "Cannot invite users from external domains. Please use @acmecorp.com email addresses." // Shown when DENY 5 } 6 } ``` ## `PRE_M2M_TOKEN_CREATION` [Section titled “PRE\_M2M\_TOKEN\_CREATION”](#pre_m2m_token_creation) Fires before issuing a machine-to-machine access token. Use this to add custom claims, modify scopes dynamically, or apply conditional access rules for service-to-service authentication. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit-3) PRE\_M2M\_TOKEN\_CREATION — request body ```json 1 { 2 "display_name": "Validate M2M client permissions", 3 "trigger_point": "PRE_M2M_TOKEN_CREATION", 4 "interceptor_context": { 5 "environment_id": "env_17002334043308132", 6 "client_id": "m2morg_93710427703245914", // M2M client requesting the token 7 "user_agent": "deployment-service/2.1.0", // Service making the request 8 "device_type": "Unknown", 9 "triggered_at": "2025-10-08T21:22:20.173Z" // ISO 8601 timestamp 10 }, 11 "data": { 12 "m2m_token_claims": { // Claims that will be included in the token 13 "client_id": "m2morg_93710427703245914", 14 "claims": { 15 "custom_claims": { // Existing custom claims from client configuration 16 "service_name": "deployment-automation", 17 "deployment_environment": "production" 18 }, 19 "oid": "org_89669394174574792", // Organization ID for this M2M client 20 "scope": "deploy:applications read:deployments write:logs", // Space-separated scopes 21 "scopes": [ // Array of individual scopes requested 22 "deploy:applications", 23 "read:deployments", 24 "write:logs" 25 ] 26 } 27 } 28 } 29 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return-3) PRE\_M2M\_TOKEN\_CREATION — response body ```json 1 { 2 "decision": "ALLOW", // Required: ALLOW to issue token, DENY to block 3 "response": { 4 "claims": { // Optional: Add or modify claims in the M2M token 5 "scope": "deploy:applications read:deployments", // Can modify scopes dynamically 6 "aud": "https://api.acmecorp.com", // Target audience for the token 7 "rate_limit": "1000", // Custom claim for rate limiting 8 "environment": "production" // Custom claim for environment context 9 } 10 } 11 } ``` --- # DOCUMENT BOUNDARY --- # Outbound IP addresses > Allowlist Scalekit's outbound IP addresses so providers and services accept the requests and tool calls that originate from Scalekit. When Scalekit makes outbound requests on your behalf, such as tool calls to upstream providers, the traffic originates from a fixed set of NAT IP addresses. If a provider or one of your own services restricts inbound traffic by IP, add these addresses to its allowlist so the provider accepts the requests. ## IP addresses by region [Section titled “IP addresses by region”](#ip-addresses-by-region) | Region | Outbound IP address | | ------------------- | ------------------- | | United States (US) | `34.94.129.140` | | European Union (EU) | `35.198.115.68` | Use the address for the region your Scalekit environment runs in. If you run environments in both regions, allowlist both addresses. ## When to allowlist these addresses [Section titled “When to allowlist these addresses”](#when-to-allowlist-these-addresses) Allowlist Scalekit’s outbound IP addresses when: * An upstream provider restricts API access to known IP addresses, and you call that provider’s tools through Scalekit. * Your own backend validates the source IP of the requests it receives from Scalekit. --- # DOCUMENT BOUNDARY --- # API rate limits > Understand Scalekit API rate limits, tell them apart from upstream provider limits, handle 429 responses, and request a higher limit. Scalekit applies a rate limit to the API requests from each environment. When a workload exceeds that limit, the API responds with HTTP `429 Too Many Requests`. This page explains how to recognize a rate-limit response, tell a Scalekit limit apart from an upstream provider’s limit, handle the response, and request a higher limit. ## How rate limits work [Section titled “How rate limits work”](#how-rate-limits-work) Scalekit enforces a per-environment request rate, measured in requests per minute. Scalekit tunes the limit per account, so high-throughput workloads can need a higher limit than the default. Routing MCP tool calls through Scalekit on top of authentication traffic is one example of a workload that can need more headroom. When you exceed the limit, Scalekit returns HTTP `429 Too Many Requests`. Back off and retry with exponential backoff rather than retrying immediately. ## Tell Scalekit limits apart from provider limits [Section titled “Tell Scalekit limits apart from provider limits”](#tell-scalekit-limits-apart-from-provider-limits) When you call tools through Scalekit, a `429` can come from either Scalekit or the upstream provider that Scalekit calls on your behalf, such as a CRM or data API. The `error_code` field on the error identifies the source: | `error_code` | Source | What to do | | -------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------- | | `RATE_LIMITED` | Scalekit’s own rate limit | Reduce the overall request frequency and back off before retrying. | | `TOOL_ERROR` | The upstream provider rate-limited the tool call | Apply the provider’s recommended backoff. Check the tool call logs for the provider’s message. | Review the detailed error in your dashboard’s tool call logs to confirm which provider and which tool triggered the limit. ## Handle a 429 response [Section titled “Handle a 429 response”](#handle-a-429-response) Every Scalekit SDK raises a dedicated exception when the API returns `429`. Catch it, read the error code to determine the source, and back off before retrying. * Node.js rate-limit-handling.ts ```ts 1 import { ScalekitTooManyRequestsException } from '@scalekit-sdk/node'; 2 3 try { 4 // Your Scalekit SDK call, for example executing a tool 5 await scalekit.tools.executeTool(/* ... */); 6 } catch (error) { 7 if (error instanceof ScalekitTooManyRequestsException) { 8 // errorCode identifies the source of the 429 so you can back off correctly 9 if (error.errorCode === 'TOOL_ERROR') { 10 // Upstream provider rate-limited the call: apply provider-specific backoff 11 console.error('Provider rate limit:', error.message); 12 } else { 13 // Scalekit's own rate limit (RATE_LIMITED): reduce overall request frequency 14 console.error('Scalekit rate limit:', error.message); 15 } 16 } 17 } ``` * Python rate\_limit\_handling.py ```py 1 from scalekit.common.exceptions import ScalekitTooManyRequestsException 2 3 try: 4 result = scalekit_client.tools.execute_tool(...) 5 except ScalekitTooManyRequestsException as e: 6 # error_code identifies the source of the 429 so you can back off correctly 7 if e.error_code == "TOOL_ERROR": 8 # Upstream provider rate-limited the call: apply provider-specific backoff 9 print("Provider rate limit:", e.message) 10 else: 11 # Scalekit's own rate limit (RATE_LIMITED): reduce overall request frequency 12 print("Scalekit rate limit:", e.message) ``` * Go rate\_limit\_handling.go ```go 1 // Your Scalekit SDK call, for example executing a tool 2 _, err := scalekitClient.Tools.ExecuteTool(ctx /* ... */) 3 if err != nil { 4 // Inspect the error code to find the source of the 429. 5 // "TOOL_ERROR" is the upstream provider's limit; "RATE_LIMITED" is Scalekit's 6 // own limit. Back off with exponential backoff before retrying. 7 log.Printf("rate limited: %v", err) 8 } ``` * Java RateLimitHandling.java ```java 1 try { 2 // Your Scalekit SDK call, for example executing a tool 3 scalekitClient.tools().executeTool(/* ... */); 4 } catch (ScalekitException error) { 5 // Inspect the error code to find the source of the 429. 6 // "TOOL_ERROR" is the upstream provider's limit; "RATE_LIMITED" is Scalekit's 7 // own limit. Back off with exponential backoff before retrying. 8 System.err.println("Rate limited: " + error.getMessage()); 9 } ``` ## Request a higher limit [Section titled “Request a higher limit”](#request-a-higher-limit) If your workload needs a higher limit, contact Scalekit support with your account details and your expected peak requests per minute. Plan ahead before you route additional traffic, such as MCP tool calls, through Scalekit. Scalekit reviews the request and adjusts the limit for your account. When you estimate the limit you need, include headroom above your current peak so that normal spikes do not trigger `429` responses. --- # DOCUMENT BOUNDARY --- # Code Samples > Explore comprehensive code samples and examples for integrating with Scalekit across different programming languages and frameworks ### [MCP Auth](/resources/code-samples/mcp-auth/) [MCP server authentication examples in Python and Node.js](/resources/code-samples/mcp-auth/) ### [Agent Auth](/agentkit/code-samples/) [Code samples for integrations with LangChain, Google ADK, and direct integrations](/agentkit/code-samples/) ### [Modular SSO](/resources/code-samples/modular-sso/) [Single Sign-On implementations for enterprise authentication with Express.js, PHP Symfony, .NET Core, Firebase, and AWS Cognito integrations](/resources/code-samples/modular-sso/) ### [Modular SCIM](/resources/code-samples/modular-scim/) [SCIM provisioning examples and integration patterns for user and group management](/resources/code-samples/modular-scim/) ### Full stack auth Complete authentication implementations across different frameworks including Next.js, Express.js, Spring Boot, FastAPI, and Go [See all code samples →](/resources/code-samples/full-stack-auth/) --- # DOCUMENT BOUNDARY --- # Full stack auth > Code samples demonstrating complete authentication implementations with hosted login and session management ### [Full Stack Auth with Next.js](https://github.com/scalekit-inc/scalekit-nextjs-auth-example) [Complete authentication solution for Next.js apps. Includes hosted login pages, session management, and protected routes](https://github.com/scalekit-inc/scalekit-nextjs-auth-example) ### [Full Stack Auth with FastAPI](https://github.com/scalekit-inc/scalekit-fastapi-auth-example) [Authentication template for FastAPI projects. Featuring integrated user sessions, hosted login flow, and ready-to-use route protection specifically tailored for Python web backends.](https://github.com/scalekit-inc/scalekit-fastapi-auth-example) ### [Full Stack Auth with Flask](https://github.com/scalekit-inc/scalekit-flask-auth-example) [Authentication template for Flask applications. Features session management, hosted login flow, and decorator-based route protection](https://github.com/scalekit-inc/scalekit-flask-auth-example) ### [Full Stack Auth with Django](https://github.com/scalekit-inc/scalekit-django-auth-example) [Authentication template for Django projects. Features session management, hosted login flow, and middleware-based route protection](https://github.com/scalekit-inc/scalekit-django-auth-example) ### [Full Stack Auth with Express](https://github.com/scalekit-inc/scalekit-express-auth-example) [Complete authentication solution for Express.js applications. Includes hosted login pages, session management, and middleware-protected routes](https://github.com/scalekit-inc/scalekit-express-auth-example) ### [Full Stack Auth with Spring Boot](https://github.com/scalekit-inc/scalekit-springboot-auth-example) [End-to-end authentication for Java applications. Features Spring Security integration, hosted login, and session handling](https://github.com/scalekit-inc/scalekit-springboot-auth-example) ### [Full Stack Auth with Laravel](https://github.com/scalekit-inc/scalekit-laravel-auth-example) [Complete authentication solution for Laravel applications. Includes hosted login pages, session management, and middleware-protected routes](https://github.com/scalekit-inc/scalekit-laravel-auth-example) ### End to end full stack auth demo Coffee Desk App Complete coffee shop management application with full stack. Features workspaces, organization switcher, and mulitple auth methods [View demo](https://dashboard.coffeedesk.app/) | [View code](https://github.com/scalekit-inc/coffee-desk-demo) --- # DOCUMENT BOUNDARY --- # MCP Auth > Model Context Protocol authentication examples and patterns ### [Add Auth to Node.js MCP Servers](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-node) [Add Scalekit auth to a Node.js MCP server with minimal setup. Includes a working example with user greeting.](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-node) ### [Add Auth to Python MCP Servers](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-python) [Add Scalekit auth to a Python MCP server in minutes. Includes a working example with user greeting.](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/greeting-mcp-python) ### [Secure FastMCP Apps with Auth](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/todo-fastmcp) [Build a secure FastMCP app with Scalekit. Features a complete todo list with protected endpoints and session management.](https://github.com/scalekit-inc/mcp-auth-demos/tree/main/todo-fastmcp) --- # DOCUMENT BOUNDARY --- # Modular SCIM > Code samples demonstrating SCIM provisioning examples and integration patterns for user and group management ### [Handle SCIM webhooks](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/webhook-events) [Process SCIM directory updates in Next.js. Example shows how to verify webhook signatures and sync user data](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/webhook-events) ### [Embed admin portal](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) [Securely embed the Scalekit Admin Portal via iframe. Node.js example for managing directory sync and organizational settings](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) --- # DOCUMENT BOUNDARY --- # Modular SSO > Code samples demonstrating Single Sign-On implementations with Express.js, PHP Symfony, .NET Core, Firebase, AWS Cognito, and Next.js ### [Add SSO to Express.js apps](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/sso-express-example) [Implement Scalekit SSO in a Node.js Express application. Includes middleware setup for secure session handling](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/sso-express-example) ### [Add SSO to PHP Symfony apps](https://github.com/scalekit-developers/scalekit-php-symfony-sso) [Call Scalekit OIDC endpoints from Symfony with no PHP SDK. Try handshake-only login or Modular SSO with a local user store](https://github.com/scalekit-developers/scalekit-php-symfony-sso) ### [Add SSO to .NET Core apps](https://github.com/scalekit-inc/dotnet-example-apps) [Secure .NET Core applications with Scalekit SSO. Demonstrates authentication pipelines and user claims management](https://github.com/scalekit-inc/dotnet-example-apps) ### [Add SSO to Spring Boot apps](https://github.com/scalekit-developers/scalekit-springboot-example) [Integrate Scalekit SSO with Spring Security. Shows how to configure security filters and protect Java endpoints](https://github.com/scalekit-developers/scalekit-springboot-example) ### [Add SSO to Python FastAPI](https://github.com/scalekit-developers/scalekit-fastapi-example) [Add enterprise SSO to FastAPI services using Scalekit. Includes async route protection and user session validation](https://github.com/scalekit-developers/scalekit-fastapi-example) ### [Add SSO to Go applications](https://github.com/scalekit-developers/scalekit-go-example) [Implement Scalekit SSO in Go. Features idiomatically written middleware for securing HTTP handlers](https://github.com/scalekit-developers/scalekit-go-example) ### [Add SSO to Next.js apps](https://github.com/scalekit-developers/scalekit-nextjs-demo) [Secure Next.js applications with Scalekit. Covers both App Router and Pages Router authentication patterns](https://github.com/scalekit-developers/scalekit-nextjs-demo) ### Scalekit SSO + Your own auth system [Section titled “Scalekit SSO + Your own auth system”](#scalekit-sso--your-own-auth-system) ### [Connect Firebase Auth with SSO](https://github.com/scalekit-inc/scalekit-firebase-sso) [Enable Enterprise SSO for Firebase apps using Scalekit. Learn to link Scalekit identities with Firebase Authentication](https://github.com/scalekit-inc/scalekit-firebase-sso) ### [Connect AWS Cognito with SSO](https://github.com/scalekit-inc/scalekit-cognito-sso) [Add Enterprise SSO to Cognito user pools via Scalekit. Step-by-step guide to federating identity providers](https://github.com/scalekit-inc/scalekit-cognito-sso) ### [Cognito + Scalekit for Next.js](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/cognito-scalekit) [Integrate Cognito and Scalekit SSO in Next.js. Uses OIDC protocols to secure your full-stack React application](https://github.com/scalekit-inc/nextjs-example-apps/tree/main/cognito-scalekit) ## Admin portal [Section titled “Admin portal”](#admin-portal) ### [Embed admin portal](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) [Embed the Scalekit Admin Portal into your app via **iframe**. Node.js example for generating secure admin sessions](https://github.com/scalekit-inc/nodejs-example-apps/tree/main/embed-admin-portal-sample) --- # DOCUMENT BOUNDARY --- # Django session middleware > Add hosted login and an encrypted session cookie to Django with ScalekitAuthMiddleware Use `scalekit.frameworks.django` to add hosted login, an encrypted `sk_session` cookie, token refresh, and logout. Typical flow: install the `django` extra, add settings and `ScalekitAuthMiddleware`, include the auth URLs, and decorate one view with `@login_required`. There is no `ScalekitAuth` instance to construct. Requires `scalekit-sdk-python` 2.17.0 or later. Register these URLs in the Scalekit Dashboard under **Authentication > Redirects** before you test. Paths have **no trailing slash**. | Dashboard field | Must match | | ---------------------------- | ----------------------------------------------------------------------------- | | **Redirect URI** | `SCALEKIT_REDIRECT_URI` exactly, for example `http://localhost:8000/callback` | | **Post Logout Redirect URI** | Absolute URL after full logout, for example `http://localhost:8000/` | | **Initiate Login URL** | Login path, for example `http://localhost:8000/login` | Store credentials in environment variables. Never hard-code secrets. .env ```bash SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=... COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32 REDIRECT_URI=http://localhost:8000/callback ``` Keep `COOKIE_ENCRYPTION_SECRET` identical on every server instance. ## Install the package [Section titled “Install the package”](#install-the-package) Terminal ```bash pip install "scalekit-sdk-python[django]" ``` ## Protect a route [Section titled “Protect a route”](#protect-a-route) settings.py ```python import os MIDDLEWARE = [ # ... "scalekit.frameworks.django.ScalekitAuthMiddleware", ] SCALEKIT_ENV_URL = os.environ["SCALEKIT_ENVIRONMENT_URL"] SCALEKIT_CLIENT_ID = os.environ["SCALEKIT_CLIENT_ID"] SCALEKIT_CLIENT_SECRET = os.environ["SCALEKIT_CLIENT_SECRET"] SCALEKIT_REDIRECT_URI = os.environ["REDIRECT_URI"] SCALEKIT_COOKIE_ENCRYPTION_SECRET = os.environ["COOKIE_ENCRYPTION_SECRET"] SCALEKIT_COOKIE_SECURE = False # set True behind HTTPS ``` urls.py ```python from django.urls import include, path from . import views urlpatterns = [ path("", include("scalekit.frameworks.django")), path("account", views.account), ] ``` views.py ```python from django.http import JsonResponse from scalekit.frameworks.django import login_required @login_required def account(request): return JsonResponse({"sub": request.scalekit_user["sub"]}) ``` Open `http://localhost:8000/account`. A missing session returns **302** to `/login`, not a JSON 401. `request.scalekit_user` is access-token claims, or `None` when the visitor is anonymous. `sub` is always present on an authenticated user. `email` appears only when you add it as a custom access-token claim. Set SCALEKIT\_COOKIE\_SECURE=False on local HTTP `SCALEKIT_COOKIE_SECURE` defaults to `True`. Set it `False` for local HTTP. Set it `True` in production. ### ScalekitAuthMiddleware [Section titled “ScalekitAuthMiddleware”](#scalekitauthmiddleware) classScalekitAuthMiddlewarehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/django.py ### login\_required [Section titled “login\_required”](#login_required) modulescalekit.frameworks.djangohttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/django.py ### get\_session [Section titled “get\_session”](#get_session) modulescalekit.frameworks.djangohttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/django.py --- # DOCUMENT BOUNDARY --- # Express session middleware > Add hosted login and an encrypted session cookie to Express with ScalekitAuth Use `ScalekitAuth` from `@scalekit-sdk/node/express` to add hosted login, an encrypted `sk_session` cookie, token refresh, and logout. Typical flow: install `@scalekit-sdk/node` 2.12.0 or later, mount `auth.router`, and guard one route with `auth.requiresAuth`. Use the methods below to change paths, logout, or pass an existing [ScalekitClient](/saaskit/sdks/node/scalekit-client/). Register these URLs in the Scalekit Dashboard under **Authentication > Redirects** before you test: | Dashboard field | Must match | | ---------------------------- | -------------------------------------------------------------------- | | **Redirect URI** | `redirectUri` exactly, for example `http://localhost:5001/callback` | | **Post Logout Redirect URI** | Absolute URL after full logout, for example `http://localhost:5001/` | | **Initiate Login URL** | Login path, for example `http://localhost:5001/login` | Store credentials in environment variables. Never hard-code secrets. .env ```bash SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=... COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32 REDIRECT_URI=http://localhost:5001/callback ``` Keep `COOKIE_ENCRYPTION_SECRET` identical on every server instance. The SDK does not ship a default. ## Install the package [Section titled “Install the package”](#install-the-package) Terminal ```bash npm install @scalekit-sdk/node express ``` `cookie-parser` is optional. `ScalekitAuth` reads the `Cookie` header when `req.cookies` is missing. ## Protect a route [Section titled “Protect a route”](#protect-a-route) server.ts ```typescript import express from 'express'; import { ScalekitAuth } from '@scalekit-sdk/node/express'; const auth = new ScalekitAuth({ envUrl: process.env.SCALEKIT_ENVIRONMENT_URL, clientId: process.env.SCALEKIT_CLIENT_ID, clientSecret: process.env.SCALEKIT_CLIENT_SECRET, redirectUri: process.env.REDIRECT_URI, cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET, }); const app = express(); app.use(auth.router); app.get('/account', auth.requiresAuth, (req, res) => { res.json({ sub: req.scalekitUser?.sub }); }); app.listen(5001); ``` Open `http://localhost:5001/account`. A missing session returns **302** to `/login?returnTo=/account`, not a JSON 401. After login, the callback restores `/account`. `req.scalekitUser` is access-token claims. `sub` is always present. `email` appears only when you add it as a custom access-token claim. Do not treat 302 as an API error A background `fetch` that follows redirects can complete a login instead of returning 401. Use `requiresAuth` on browser navigations, not as a JSON API gate. ### constructor [Section titled “constructor”](#constructor) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/express.ts ### requiresAuth [Section titled “requiresAuth”](#requiresauth) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/express.ts ### router [Section titled “router”](#router) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/express.ts --- # DOCUMENT BOUNDARY --- # FastAPI session middleware > Add hosted login and an encrypted session cookie to FastAPI with ScalekitAuth Use `ScalekitAuth` from `scalekit.frameworks.fastapi` to add hosted login, an encrypted `sk_session` cookie, token refresh, and logout. Typical flow: install the `fastapi` extra, call `auth.install(app)`, and protect an endpoint with `Depends(auth.requires_auth)`. Requires `scalekit-sdk-python` 2.17.0 or later. Register these URLs in the Scalekit Dashboard under **Authentication > Redirects** before you test: | Dashboard field | Must match | | ---------------------------- | -------------------------------------------------------------------- | | **Redirect URI** | `redirect_uri` exactly, for example `http://localhost:5001/callback` | | **Post Logout Redirect URI** | Absolute URL after full logout, for example `http://localhost:5001/` | | **Initiate Login URL** | Login path, for example `http://localhost:5001/login` | Store credentials in environment variables. Never hard-code secrets. .env ```bash SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=... COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32 REDIRECT_URI=http://localhost:5001/callback ``` Keep `COOKIE_ENCRYPTION_SECRET` identical on every server instance. ## Install the package [Section titled “Install the package”](#install-the-package) Terminal ```bash pip install "scalekit-sdk-python[fastapi]" ``` ## Protect a route [Section titled “Protect a route”](#protect-a-route) app.py ```python import os from fastapi import Depends, FastAPI from scalekit.frameworks.fastapi import ScalekitAuth app = FastAPI() auth = ScalekitAuth( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], redirect_uri=os.environ["REDIRECT_URI"], cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], cookie_secure=False, # set True behind HTTPS ) auth.install(app) @app.get("/account") async def account(user: dict = Depends(auth.requires_auth)): return {"sub": user["sub"]} ``` Open `http://localhost:5001/account`. A missing session returns **302** to `/login`, not a JSON 401. `user` is access-token claims. `sub` is always present. `email` appears only when you add it as a custom access-token claim. Set cookie\_secure=False on local HTTP `cookie_secure` defaults to `True`. Set `cookie_secure=False` for local HTTP. Set it `True` in production. ### constructor [Section titled “constructor”](#constructor) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/fastapi.py ### install [Section titled “install”](#install) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/fastapi.py ### requires\_auth [Section titled “requires\_auth”](#requires_auth) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/fastapi.py ### get\_session [Section titled “get\_session”](#get_session) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/fastapi.py --- # DOCUMENT BOUNDARY --- # Flask session middleware > Add hosted login and an encrypted session cookie to Flask with ScalekitAuth Use `ScalekitAuth` from `scalekit.frameworks.flask` to add hosted login, an encrypted `sk_session` cookie, token refresh, and logout. Typical flow: install the `flask` extra, construct `ScalekitAuth` with the Flask app, and decorate one view with `@auth.requires_auth`. Requires `scalekit-sdk-python` 2.17.0 or later. Register these URLs in the Scalekit Dashboard under **Authentication > Redirects** before you test: | Dashboard field | Must match | | ---------------------------- | -------------------------------------------------------------------- | | **Redirect URI** | `redirect_uri` exactly, for example `http://localhost:5001/callback` | | **Post Logout Redirect URI** | Absolute URL after full logout, for example `http://localhost:5001/` | | **Initiate Login URL** | Login path, for example `http://localhost:5001/login` | Store credentials in environment variables. Never hard-code secrets. .env ```bash SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=... COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32 REDIRECT_URI=http://localhost:5001/callback ``` Keep `COOKIE_ENCRYPTION_SECRET` identical on every server instance. The SDK does not ship a default. ## Install the package [Section titled “Install the package”](#install-the-package) Terminal ```bash pip install "scalekit-sdk-python[flask]" ``` ## Protect a route [Section titled “Protect a route”](#protect-a-route) app.py ```python import os from flask import Flask from scalekit.frameworks.flask import ScalekitAuth app = Flask(__name__) auth = ScalekitAuth( app, env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], redirect_uri=os.environ["REDIRECT_URI"], cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"], cookie_secure=False, # set True behind HTTPS ) @app.route("/account") @auth.requires_auth def account(): return {"sub": auth.current_user["sub"]} ``` Open `http://localhost:5001/account`. A missing session returns **302** to `/login`, not a JSON 401. `auth.current_user` is access-token claims. `sub` is always present. `email` appears only when you add it as a custom access-token claim. Set cookie\_secure=False on local HTTP `cookie_secure` defaults to `True`. Some browsers drop a `Secure` cookie on plain `http://localhost`, which looks like a session that never sticks. Set `cookie_secure=False` for local HTTP. Set it `True` in production. ### constructor [Section titled “constructor”](#constructor) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/flask.py ### init\_app [Section titled “init\_app”](#init_app) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/flask.py ### requires\_auth [Section titled “requires\_auth”](#requires_auth) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/flask.py ### current\_user [Section titled “current\_user”](#current_user) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/flask.py ### get\_session [Section titled “get\_session”](#get_session) classScalekitAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/frameworks/flask.py --- # DOCUMENT BOUNDARY --- # API tokens > API tokens for service access Create and validate API tokens for programmatic access to Scalekit APIs. Use tokens for service access that is not a full end-user session. Create a token, store it securely, and validate it on incoming requests. ### CreateToken [Section titled “CreateToken”](#createtoken) clientAPITokenshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/token.go ### ValidateToken [Section titled “ValidateToken”](#validatetoken) clientAPITokenshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/token.go ### InvalidateToken [Section titled “InvalidateToken”](#invalidatetoken) clientAPITokenshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/token.go ### ListTokens [Section titled “ListTokens”](#listtokens) clientAPITokenshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/token.go ### UpdateToken [Section titled “UpdateToken”](#updatetoken) clientAPITokenshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/token.go --- # DOCUMENT BOUNDARY --- # Authorization > Authorization helpers for protected resources Use auth helpers for authorization code exchange, token validation, and related login token flows on the Scalekit client. These methods sit next to session management—use them when implementing hosted login callbacks and token checks. ### UpdateLoginUserDetails [Section titled “UpdateLoginUserDetails”](#updateloginuserdetails) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/auth\_service.go --- # DOCUMENT BOUNDARY --- # OAuth clients > OAuth clients for applications Manage OAuth clients for applications that use Scalekit as an authorization server. Register clients for your apps, rotate secrets carefully, and scope clients to the right application type. ### CreateClient [Section titled “CreateClient”](#createclient) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go ### GetClient [Section titled “GetClient”](#getclient) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go ### ListClients [Section titled “ListClients”](#listclients) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go ### UpdateClient [Section titled “UpdateClient”](#updateclient) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go ### DeleteClient [Section titled “DeleteClient”](#deleteclient) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go ### AddClientSecret [Section titled “AddClientSecret”](#addclientsecret) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go ### RemoveClientSecret [Section titled “RemoveClientSecret”](#removeclientsecret) clientClientshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/clients.go --- # DOCUMENT BOUNDARY --- # Connections > Configure enterprise SSO connections Use the connection client to configure enterprise SSO (SAML/OIDC) for an organization. Enable SSO after the organization exists: create a connection, complete IdP setup, and test sign-in for that org. ### CreateConnection [Section titled “CreateConnection”](#createconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go ### DeleteConnection [Section titled “DeleteConnection”](#deleteconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go ### GetConnection [Section titled “GetConnection”](#getconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go ### ListConnectionsByDomain [Section titled “ListConnectionsByDomain”](#listconnectionsbydomain) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go ### ListConnections [Section titled “ListConnections”](#listconnections) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go ### EnableConnection [Section titled “EnableConnection”](#enableconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go ### DisableConnection [Section titled “DisableConnection”](#disableconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/connection.go --- # DOCUMENT BOUNDARY --- # Directory > Sync users and groups via SCIM directories Use the directory client for SCIM directory sync—listing providers, users, and groups provisioned from an IdP. Use this after SSO is in place when the customer provisions users via SCIM. ### CreateDirectory [Section titled “CreateDirectory”](#createdirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### DeleteDirectory [Section titled “DeleteDirectory”](#deletedirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### ListDirectories [Section titled “ListDirectories”](#listdirectories) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### GetDirectory [Section titled “GetDirectory”](#getdirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### GetPrimaryDirectoryByOrganizationId [Section titled “GetPrimaryDirectoryByOrganizationId”](#getprimarydirectorybyorganizationid) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### ListDirectoryUsers [Section titled “ListDirectoryUsers”](#listdirectoryusers) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### ListDirectoryGroups [Section titled “ListDirectoryGroups”](#listdirectorygroups) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### EnableDirectory [Section titled “EnableDirectory”](#enabledirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go ### DisableDirectory [Section titled “DisableDirectory”](#disabledirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/directory.go --- # DOCUMENT BOUNDARY --- # Domains > Manage organization email domains Use the domain client to manage verified email domains for an organization (SSO routing and domain-based policies). Add a domain, complete verification, then use it with SSO and organization policies. ### CreateDomain [Section titled “CreateDomain”](#createdomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/domain.go ### GetDomain [Section titled “GetDomain”](#getdomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/domain.go ### ListDomains [Section titled “ListDomains”](#listdomains) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/domain.go ### DeleteDomain [Section titled “DeleteDomain”](#deletedomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/domain.go --- # DOCUMENT BOUNDARY --- # M2M clients > Machine-to-machine clients and tokens Use the M2M client to create and manage machine-to-machine OAuth clients and secrets for service-to-service auth. Create an M2M client, store the secret securely, then obtain tokens with client credentials. ### CreateOrganizationClient [Section titled “CreateOrganizationClient”](#createorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go ### GetOrganizationClient [Section titled “GetOrganizationClient”](#getorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go ### UpdateOrganizationClient [Section titled “UpdateOrganizationClient”](#updateorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go ### DeleteOrganizationClient [Section titled “DeleteOrganizationClient”](#deleteorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go ### CreateOrganizationClientSecret [Section titled “CreateOrganizationClientSecret”](#createorganizationclientsecret) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go ### DeleteOrganizationClientSecret [Section titled “DeleteOrganizationClientSecret”](#deleteorganizationclientsecret) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go ### ListOrganizationClients [Section titled “ListOrganizationClients”](#listorganizationclients) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/m2mclient.go --- # DOCUMENT BOUNDARY --- # Organizations > Manage your customer organizations Use the Organization client to create and manage customer tenants (organizations) in your Scalekit application. Start here when onboarding a new customer: create an organization, set external IDs and branding, then add users and SSO for that org. ### CreateOrganization [Section titled “CreateOrganization”](#createorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### ListOrganization [Section titled “ListOrganization”](#listorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### GetOrganization [Section titled “GetOrganization”](#getorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### GetOrganizationByExternalId [Section titled “GetOrganizationByExternalId”](#getorganizationbyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### UpdateOrganization [Section titled “UpdateOrganization”](#updateorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### UpdateOrganizationByExternalId [Section titled “UpdateOrganizationByExternalId”](#updateorganizationbyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### DeleteOrganization [Section titled “DeleteOrganization”](#deleteorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### GeneratePortalLink [Section titled “GeneratePortalLink”](#generateportallink) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### UpdateOrganizationSettings [Section titled “UpdateOrganizationSettings”](#updateorganizationsettings) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### UpsertUserManagementSettings [Section titled “UpsertUserManagementSettings”](#upsertusermanagementsettings) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### GetOrganizationSessionPolicy [Section titled “GetOrganizationSessionPolicy”](#getorganizationsessionpolicy) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go ### UpdateOrganizationSessionPolicy [Section titled “UpdateOrganizationSessionPolicy”](#updateorganizationsessionpolicy) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/organization.go --- # DOCUMENT BOUNDARY --- # Magic link & OTP > Send and verify passwordless login codes Use the passwordless client to send and verify email magic links or one-time codes for sign-in. Call send, then verify with the code or link token from the user’s email to complete login. ### SendPasswordlessEmail [Section titled “SendPasswordlessEmail”](#sendpasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/passwordless.go ### VerifyPasswordlessEmail [Section titled “VerifyPasswordlessEmail”](#verifypasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/passwordless.go ### ResendPasswordlessEmail [Section titled “ResendPasswordlessEmail”](#resendpasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/passwordless.go --- # DOCUMENT BOUNDARY --- # Permissions > Manage fine-grained permissions Use the permission client to define fine-grained permissions that roles can grant. Model permissions for resources in your app, then attach them to roles. ### CreatePermission [Section titled “CreatePermission”](#createpermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### GetPermission [Section titled “GetPermission”](#getpermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### ListPermissions [Section titled “ListPermissions”](#listpermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### UpdatePermission [Section titled “UpdatePermission”](#updatepermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### DeletePermission [Section titled “DeletePermission”](#deletepermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### ListRolePermissions [Section titled “ListRolePermissions”](#listrolepermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### AddPermissionsToRole [Section titled “AddPermissionsToRole”](#addpermissionstorole) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### RemovePermissionFromRole [Section titled “RemovePermissionFromRole”](#removepermissionfromrole) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go ### ListEffectiveRolePermissions [Section titled “ListEffectiveRolePermissions”](#listeffectiverolepermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/permission.go --- # DOCUMENT BOUNDARY --- # Roles > Define and assign organization roles Use the role client to define organization roles and list role assignments. Create roles and permissions for authorization after you have organizations and users. ### CreateRole [Section titled “CreateRole”](#createrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### GetRole [Section titled “GetRole”](#getrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### ListRoles [Section titled “ListRoles”](#listroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### UpdateRole [Section titled “UpdateRole”](#updaterole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### DeleteRole [Section titled “DeleteRole”](#deleterole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### GetRoleUsersCount [Section titled “GetRoleUsersCount”](#getroleuserscount) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### CreateOrganizationRole [Section titled “CreateOrganizationRole”](#createorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### GetOrganizationRole [Section titled “GetOrganizationRole”](#getorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### ListOrganizationRoles [Section titled “ListOrganizationRoles”](#listorganizationroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### UpdateOrganizationRole [Section titled “UpdateOrganizationRole”](#updateorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### DeleteOrganizationRole [Section titled “DeleteOrganizationRole”](#deleteorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### GetOrganizationRoleUsersCount [Section titled “GetOrganizationRoleUsersCount”](#getorganizationroleuserscount) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### UpdateDefaultOrganizationRoles [Section titled “UpdateDefaultOrganizationRoles”](#updatedefaultorganizationroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### DeleteOrganizationRoleBase [Section titled “DeleteOrganizationRoleBase”](#deleteorganizationrolebase) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### DeleteRoleBase [Section titled “DeleteRoleBase”](#deleterolebase) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### UpdateDefaultRoles [Section titled “UpdateDefaultRoles”](#updatedefaultroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go ### ListDependentRoles [Section titled “ListDependentRoles”](#listdependentroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/role.go --- # DOCUMENT BOUNDARY --- # Create client > Create the SDK client and run core auth helpers Create a Scalekit client with your environment URL, client ID, and client secret. All other clients hang off this instance. Store credentials in environment variables. Never hard-code secrets. After you create the client, use [Sessions](/saaskit/sdks/go/sessions/) or domain clients such as [Organizations](/saaskit/sdks/go/organizations/) and [Users](/saaskit/sdks/go/users/). ### GetAuthorizationUrl [Section titled “GetAuthorizationUrl”](#getauthorizationurl) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### AuthenticateWithCode [Section titled “AuthenticateWithCode”](#authenticatewithcode) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### GetIdpInitiatedLoginClaims [Section titled “GetIdpInitiatedLoginClaims”](#getidpinitiatedloginclaims) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### GetAccessTokenClaims [Section titled “GetAccessTokenClaims”](#getaccesstokenclaims) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### ValidateAccessToken [Section titled “ValidateAccessToken”](#validateaccesstoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### RefreshAccessToken [Section titled “RefreshAccessToken”](#refreshaccesstoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### GetLogoutUrl [Section titled “GetLogoutUrl”](#getlogouturl) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### VerifyWebhookPayload [Section titled “VerifyWebhookPayload”](#verifywebhookpayload) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### VerifyInterceptorPayload [Section titled “VerifyInterceptorPayload”](#verifyinterceptorpayload) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Connection [Section titled “Connection”](#connection) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Organization [Section titled “Organization”](#organization) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### User [Section titled “User”](#user) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Domain [Section titled “Domain”](#domain) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Directory [Section titled “Directory”](#directory) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Session [Section titled “Session”](#session) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Role [Section titled “Role”](#role) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Permission [Section titled “Permission”](#permission) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Passwordless [Section titled “Passwordless”](#passwordless) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### WebAuthn [Section titled “WebAuthn”](#webauthn) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Auth [Section titled “Auth”](#auth) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Client [Section titled “Client”](#client) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### Token [Section titled “Token”](#token) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### ValidateTokenWithOptions [Section titled “ValidateTokenWithOptions”](#validatetokenwithoptions) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### ValidateToken [Section titled “ValidateToken”](#validatetoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### WithSecret [Section titled “WithSecret”](#withsecret) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### GenerateClientToken [Section titled “GenerateClientToken”](#generateclienttoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### GetClientAccessToken [Section titled “GetClientAccessToken”](#getclientaccesstoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### UnmarshalJSON [Section titled “UnmarshalJSON”](#unmarshaljson) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### M2M [Section titled “M2M”](#m2m) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go ### VerifyPayloadSignature [Section titled “VerifyPayloadSignature”](#verifypayloadsignature) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/scalekit.go --- # DOCUMENT BOUNDARY --- # Sessions > Validate tokens and manage user sessions Use the Session client to inspect session metadata and revoke sessions when users sign out or you detect risk. Typical flows: load a session by ID after authentication, list a user’s sessions for a security UI, and revoke one session or all of a user’s sessions on logout. ### GetSession [Section titled “GetSession”](#getsession) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/sessions.go ### GetUserSessions [Section titled “GetUserSessions”](#getusersessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/sessions.go ### RevokeSession [Section titled “RevokeSession”](#revokesession) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/sessions.go ### RevokeAllUserSessions [Section titled “RevokeAllUserSessions”](#revokeallusersessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/sessions.go --- # DOCUMENT BOUNDARY --- # Users > Provision and manage users and memberships Use the User client to provision people, manage organization memberships, and assign roles. Common flows: invite or create a user, attach them to an organization, update profile fields, and look up users by Scalekit ID or your external ID. ### ListUsers [Section titled “ListUsers”](#listusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### ListOrganizationUsers [Section titled “ListOrganizationUsers”](#listorganizationusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### GetUser [Section titled “GetUser”](#getuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### UpdateUser [Section titled “UpdateUser”](#updateuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### CreateUserAndMembership [Section titled “CreateUserAndMembership”](#createuserandmembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### DeleteUser [Section titled “DeleteUser”](#deleteuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### CreateMembership [Section titled “CreateMembership”](#createmembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### UpdateMembership [Section titled “UpdateMembership”](#updatemembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### DeleteMembership [Section titled “DeleteMembership”](#deletemembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### ResendInvite [Section titled “ResendInvite”](#resendinvite) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### GetUserByExternalId [Section titled “GetUserByExternalId”](#getuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### UpdateUserByExternalId [Section titled “UpdateUserByExternalId”](#updateuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### DeleteUserByExternalId [Section titled “DeleteUserByExternalId”](#deleteuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### CreateMembershipByExternalId [Section titled “CreateMembershipByExternalId”](#createmembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### UpdateMembershipByExternalId [Section titled “UpdateMembershipByExternalId”](#updatemembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### DeleteMembershipByExternalId [Section titled “DeleteMembershipByExternalId”](#deletemembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### ListUserRoles [Section titled “ListUserRoles”](#listuserroles) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go ### ListUserPermissions [Section titled “ListUserPermissions”](#listuserpermissions) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/users.go --- # DOCUMENT BOUNDARY --- # Passkeys > Passkey and WebAuthn credentials Use the WebAuthn client to register and authenticate passkeys (WebAuthn credentials). Build registration and authentication ceremonies with the options and verification methods below. ### ListCredentials [Section titled “ListCredentials”](#listcredentials) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/webauthn.go ### UpdateCredential [Section titled “UpdateCredential”](#updatecredential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/webauthn.go ### DeleteCredential [Section titled “DeleteCredential”](#deletecredential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-go/blob/main/webauthn.go --- # DOCUMENT BOUNDARY --- # Authorization > Authorization helpers for protected resources Use auth helpers for authorization code exchange, token validation, and related login token flows on the Scalekit client. These methods sit next to session management—use them when implementing hosted login callbacks and token checks. ### getAuthorizationUrl [Section titled “getAuthorizationUrl”](#getauthorizationurl) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/AuthClient.java ### validateAccessToken [Section titled “validateAccessToken”](#validateaccesstoken) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/AuthClient.java ### generateClientToken [Section titled “generateClientToken”](#generateclienttoken) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/AuthClient.java ### getClientAccessToken [Section titled “getClientAccessToken”](#getclientaccesstoken) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/AuthClient.java ### authenticateWithCode [Section titled “authenticateWithCode”](#authenticatewithcode) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/AuthClient.java ### updateLoginUserDetails [Section titled “updateLoginUserDetails”](#updateloginuserdetails) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/LoginClient.java --- # DOCUMENT BOUNDARY --- # Connections > Configure enterprise SSO connections Use `scalekitClient.connections()` to configure enterprise SSO (SAML/OIDC) for an organization. Enable SSO after the organization exists: create a connection, complete IdP setup, and test sign-in for that org. ### getConnectionById [Section titled “getConnectionById”](#getconnectionbyid) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java ### listConnectionsByDomain [Section titled “listConnectionsByDomain”](#listconnectionsbydomain) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java ### listConnectionsByOrganization [Section titled “listConnectionsByOrganization”](#listconnectionsbyorganization) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java ### enableConnection [Section titled “enableConnection”](#enableconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java ### disableConnection [Section titled “disableConnection”](#disableconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java ### createConnection [Section titled “createConnection”](#createconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java ### deleteConnection [Section titled “deleteConnection”](#deleteconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/ConnectionClient.java --- # DOCUMENT BOUNDARY --- # Directory > Sync users and groups via SCIM directories Use `scalekitClient.directories()` for SCIM directory sync—listing providers, users, and groups provisioned from an IdP. Use this after SSO is in place when the customer provisions users via SCIM. ### getDirectory [Section titled “getDirectory”](#getdirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### listDirectories [Section titled “listDirectories”](#listdirectories) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### listDirectoryUsers [Section titled “listDirectoryUsers”](#listdirectoryusers) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### listDirectoryGroups [Section titled “listDirectoryGroups”](#listdirectorygroups) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### enableDirectory [Section titled “enableDirectory”](#enabledirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### disableDirectory [Section titled “disableDirectory”](#disabledirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### getPrimaryDirectoryByOrganizationId [Section titled “getPrimaryDirectoryByOrganizationId”](#getprimarydirectorybyorganizationid) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### createDirectory [Section titled “createDirectory”](#createdirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java ### deleteDirectory [Section titled “deleteDirectory”](#deletedirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DirectoryClient.java --- # DOCUMENT BOUNDARY --- # Domains > Manage organization email domains Use `scalekitClient.domains()` to manage verified email domains for an organization (SSO routing and domain-based policies). Add a domain, complete verification, then use it with SSO and organization policies. ### createDomain [Section titled “createDomain”](#createdomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DomainClient.java ### getDomainById [Section titled “getDomainById”](#getdomainbyid) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DomainClient.java ### listDomainsByOrganizationId [Section titled “listDomainsByOrganizationId”](#listdomainsbyorganizationid) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DomainClient.java ### deleteDomain [Section titled “deleteDomain”](#deletedomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/DomainClient.java --- # DOCUMENT BOUNDARY --- # M2M clients > Machine-to-machine clients and tokens Use M2M client APIs to create and manage machine-to-machine OAuth clients and secrets for service-to-service auth. Create an M2M client, store the secret securely, then obtain tokens with client credentials. ### createOrganizationClient [Section titled “createOrganizationClient”](#createorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java ### getOrganizationClient [Section titled “getOrganizationClient”](#getorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java ### updateOrganizationClient [Section titled “updateOrganizationClient”](#updateorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java ### deleteOrganizationClient [Section titled “deleteOrganizationClient”](#deleteorganizationclient) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java ### addOrganizationClientSecret [Section titled “addOrganizationClientSecret”](#addorganizationclientsecret) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java ### removeOrganizationClientSecret [Section titled “removeOrganizationClientSecret”](#removeorganizationclientsecret) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java ### listOrganizationClients [Section titled “listOrganizationClients”](#listorganizationclients) clientM2Mhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/M2MClient.java --- # DOCUMENT BOUNDARY --- # Organizations > Manage your customer organizations Use `scalekitClient.organizations()` to create and manage customer tenants (organizations) in your Scalekit application. Start here when onboarding a new customer: create an organization, set external IDs and branding, then add users and SSO for that org. ### create [Section titled “create”](#create) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### getById [Section titled “getById”](#getbyid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### getByExternalId [Section titled “getByExternalId”](#getbyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### updateById [Section titled “updateById”](#updatebyid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### updateByExternalId [Section titled “updateByExternalId”](#updatebyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### deleteById [Section titled “deleteById”](#deletebyid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### deleteByExternalId [Section titled “deleteByExternalId”](#deletebyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### listOrganizations [Section titled “listOrganizations”](#listorganizations) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### generatePortalLink [Section titled “generatePortalLink”](#generateportallink) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### updateOrganizationSettings [Section titled “updateOrganizationSettings”](#updateorganizationsettings) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### upsertUserManagementSettings [Section titled “upsertUserManagementSettings”](#upsertusermanagementsettings) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### getOrganizationSessionPolicy [Section titled “getOrganizationSessionPolicy”](#getorganizationsessionpolicy) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java ### updateOrganizationSessionPolicy [Section titled “updateOrganizationSessionPolicy”](#updateorganizationsessionpolicy) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/OrganizationClient.java --- # DOCUMENT BOUNDARY --- # Magic link & OTP > Send and verify passwordless login codes Use `scalekitClient.passwordless()` to send and verify email magic links or one-time codes for sign-in. Call send, then verify with the code or link token from the user’s email to complete login. ### sendPasswordlessEmail [Section titled “sendPasswordlessEmail”](#sendpasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PasswordlessClient.java ### verifyPasswordlessEmail [Section titled “verifyPasswordlessEmail”](#verifypasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PasswordlessClient.java ### resendPasswordlessEmail [Section titled “resendPasswordlessEmail”](#resendpasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PasswordlessClient.java --- # DOCUMENT BOUNDARY --- # Permissions > Manage fine-grained permissions Use `scalekitClient.permissions()` to define fine-grained permissions that roles can grant. Model permissions for resources in your app, then attach them to roles. ### createPermission [Section titled “createPermission”](#createpermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### getPermission [Section titled “getPermission”](#getpermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### listPermissions [Section titled “listPermissions”](#listpermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### updatePermission [Section titled “updatePermission”](#updatepermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### deletePermission [Section titled “deletePermission”](#deletepermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### listRolePermissions [Section titled “listRolePermissions”](#listrolepermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### addPermissionsToRole [Section titled “addPermissionsToRole”](#addpermissionstorole) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### removePermissionFromRole [Section titled “removePermissionFromRole”](#removepermissionfromrole) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java ### listEffectiveRolePermissions [Section titled “listEffectiveRolePermissions”](#listeffectiverolepermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/PermissionClient.java --- # DOCUMENT BOUNDARY --- # Roles > Define and assign organization roles Use `scalekitClient.roles()` to define organization roles and list role assignments. Create roles and permissions for authorization after you have organizations and users. ### createRole [Section titled “createRole”](#createrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### getRole [Section titled “getRole”](#getrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### listRoles [Section titled “listRoles”](#listroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### updateRole [Section titled “updateRole”](#updaterole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### deleteRole [Section titled “deleteRole”](#deleterole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### getRoleUsersCount [Section titled “getRoleUsersCount”](#getroleuserscount) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### createOrganizationRole [Section titled “createOrganizationRole”](#createorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### getOrganizationRole [Section titled “getOrganizationRole”](#getorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### listOrganizationRoles [Section titled “listOrganizationRoles”](#listorganizationroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### updateOrganizationRole [Section titled “updateOrganizationRole”](#updateorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### deleteOrganizationRole [Section titled “deleteOrganizationRole”](#deleteorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### getOrganizationRoleUsersCount [Section titled “getOrganizationRoleUsersCount”](#getorganizationroleuserscount) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### updateDefaultOrganizationRoles [Section titled “updateDefaultOrganizationRoles”](#updatedefaultorganizationroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### updateDefaultRoles [Section titled “updateDefaultRoles”](#updatedefaultroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### listDependentRoles [Section titled “listDependentRoles”](#listdependentroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### deleteRoleBase [Section titled “deleteRoleBase”](#deleterolebase) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java ### deleteOrganizationRoleBase [Section titled “deleteOrganizationRoleBase”](#deleteorganizationrolebase) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/RoleClient.java --- # DOCUMENT BOUNDARY --- # Create client > Create the SDK client and run core auth helpers Create a `ScalekitClient` with your environment URL, client ID, and client secret. All other clients hang off this instance. Store credentials in environment variables. Never hard-code secrets. After you create the client, use [Sessions](/saaskit/sdks/java/sessions/) or domain clients such as [Organizations](/saaskit/sdks/java/organizations/) and [Users](/saaskit/sdks/java/users/). ### ScalekitClient [Section titled “ScalekitClient”](#scalekitclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitAuthClient [Section titled “ScalekitAuthClient”](#scalekitauthclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitCredentials [Section titled “ScalekitCredentials”](#scalekitcredentials) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitOrganizationClient [Section titled “ScalekitOrganizationClient”](#scalekitorganizationclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitDomainClient [Section titled “ScalekitDomainClient”](#scalekitdomainclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitConnectionClient [Section titled “ScalekitConnectionClient”](#scalekitconnectionclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitDirectoryClient [Section titled “ScalekitDirectoryClient”](#scalekitdirectoryclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitUserClient [Section titled “ScalekitUserClient”](#scalekituserclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitPasswordlessClient [Section titled “ScalekitPasswordlessClient”](#scalekitpasswordlessclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitRoleClient [Section titled “ScalekitRoleClient”](#scalekitroleclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitPermissionClient [Section titled “ScalekitPermissionClient”](#scalekitpermissionclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitSessionClient [Section titled “ScalekitSessionClient”](#scalekitsessionclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitWebAuthnClient [Section titled “ScalekitWebAuthnClient”](#scalekitwebauthnclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitTokenClient [Section titled “ScalekitTokenClient”](#scalekittokenclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitM2MClient [Section titled “ScalekitM2MClient”](#scalekitm2mclient) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### ScalekitWebhook [Section titled “ScalekitWebhook”](#scalekitwebhook) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### APIException [Section titled “APIException”](#apiexception) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### organizations [Section titled “organizations”](#organizations) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### domains [Section titled “domains”](#domains) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### connections [Section titled “connections”](#connections) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### authentication [Section titled “authentication”](#authentication) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### webhook [Section titled “webhook”](#webhook) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### directories [Section titled “directories”](#directories) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### users [Section titled “users”](#users) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### passwordless [Section titled “passwordless”](#passwordless) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### roles [Section titled “roles”](#roles) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### permissions [Section titled “permissions”](#permissions) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### sessions [Section titled “sessions”](#sessions) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### webAuthn [Section titled “webAuthn”](#webauthn) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### tokens [Section titled “tokens”](#tokens) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java ### m2m [Section titled “m2m”](#m2m) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/ScalekitClient.java --- # DOCUMENT BOUNDARY --- # Sessions > Validate tokens and manage user sessions Use `scalekitClient.sessions()` to inspect session metadata and revoke sessions when users sign out or you detect risk. Typical flows: load a session by ID after authentication, list a user’s sessions for a security UI, and revoke one session or all of a user’s sessions on logout. ### getSession [Section titled “getSession”](#getsession) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/SessionClient.java ### getUserSessions [Section titled “getUserSessions”](#getusersessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/SessionClient.java ### revokeSession [Section titled “revokeSession”](#revokesession) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/SessionClient.java ### revokeAllUserSessions [Section titled “revokeAllUserSessions”](#revokeallusersessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/SessionClient.java --- # DOCUMENT BOUNDARY --- # Token helpers > Token helpers and verification Create and validate API tokens for programmatic access to Scalekit APIs in Java. Use tokens for service access that is not a full end-user session. Create a token, store it securely, and validate it on incoming requests. ### create [Section titled “create”](#create) clientTokenshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/TokenClient.java ### validate [Section titled “validate”](#validate) clientTokenshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/TokenClient.java ### invalidate [Section titled “invalidate”](#invalidate) clientTokenshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/TokenClient.java ### list [Section titled “list”](#list) clientTokenshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/TokenClient.java ### update [Section titled “update”](#update) clientTokenshttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/TokenClient.java --- # DOCUMENT BOUNDARY --- # Users > Provision and manage users and memberships Use `scalekitClient.users()` to provision people, manage organization memberships, and assign roles. Common flows: invite or create a user, attach them to an organization, update profile fields, and look up users by Scalekit ID or your external ID. ### createUserAndMembership [Section titled “createUserAndMembership”](#createuserandmembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### getUser [Section titled “getUser”](#getuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### listUsers [Section titled “listUsers”](#listusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### updateUser [Section titled “updateUser”](#updateuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### deleteUser [Section titled “deleteUser”](#deleteuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### createMembership [Section titled “createMembership”](#createmembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### deleteMembership [Section titled “deleteMembership”](#deletemembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### updateMembership [Section titled “updateMembership”](#updatemembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### listOrganizationUsers [Section titled “listOrganizationUsers”](#listorganizationusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### searchUsers [Section titled “searchUsers”](#searchusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### searchOrganizationUsers [Section titled “searchOrganizationUsers”](#searchorganizationusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### resendInvite [Section titled “resendInvite”](#resendinvite) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### listUserRoles [Section titled “listUserRoles”](#listuserroles) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### listUserPermissions [Section titled “listUserPermissions”](#listuserpermissions) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### getUserByExternalId [Section titled “getUserByExternalId”](#getuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### updateUserByExternalId [Section titled “updateUserByExternalId”](#updateuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### deleteUserByExternalId [Section titled “deleteUserByExternalId”](#deleteuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### createMembershipByExternalId [Section titled “createMembershipByExternalId”](#createmembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### deleteMembershipByExternalId [Section titled “deleteMembershipByExternalId”](#deletemembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java ### updateMembershipByExternalId [Section titled “updateMembershipByExternalId”](#updatemembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/UserClient.java --- # DOCUMENT BOUNDARY --- # Passkeys > Passkey and WebAuthn credentials Use `scalekitClient.webAuthn()` to register and authenticate passkeys (WebAuthn credentials). Build registration and authentication ceremonies with the options and verification methods below. ### listCredentials [Section titled “listCredentials”](#listcredentials) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/WebAuthnClient.java ### updateCredential [Section titled “updateCredential”](#updatecredential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/WebAuthnClient.java ### deleteCredential [Section titled “deleteCredential”](#deletecredential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-java/blob/main/src/main/java/com/scalekit/api/WebAuthnClient.java --- # DOCUMENT BOUNDARY --- # Next.js session middleware > Add hosted login and an encrypted session cookie to the Next.js App Router Use `ScalekitAuthNext` from `@scalekit-sdk/node/next` to add hosted login, an encrypted `sk_session` cookie, token refresh, and logout to the App Router. Typical flow: create one `auth` instance, export login/callback/logout Route Handlers, and wrap a protected handler with `withAuth`. Use `createMiddleware()` to fail closed on every other path. For Edge Runtime, pass `ScalekitEdgeClient` instead of `ScalekitClient`. Requires `@scalekit-sdk/node` 2.12.0 or later. Register these URLs in the Scalekit Dashboard under **Authentication > Redirects** before you test: | Dashboard field | Must match | | ---------------------------- | -------------------------------------------------------------------- | | **Redirect URI** | `redirectUri` exactly, for example `http://localhost:3000/callback` | | **Post Logout Redirect URI** | Absolute URL after full logout, for example `http://localhost:3000/` | | **Initiate Login URL** | Login path, for example `http://localhost:3000/login` | Store credentials in environment variables. Never hard-code secrets. .env ```bash SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com SCALEKIT_CLIENT_ID=skc_... SCALEKIT_CLIENT_SECRET=... COOKIE_ENCRYPTION_SECRET= # openssl rand -base64 32 REDIRECT_URI=http://localhost:3000/callback ``` Keep `COOKIE_ENCRYPTION_SECRET` identical on every server instance. ## Install the package [Section titled “Install the package”](#install-the-package) Terminal ```bash npm install @scalekit-sdk/node ``` ## Protect a route [Section titled “Protect a route”](#protect-a-route) `ScalekitAuthNext` requires a `client`. It does not accept `envUrl` alone. lib/auth.ts ```typescript import ScalekitClient from '@scalekit-sdk/node'; import { ScalekitAuthNext } from '@scalekit-sdk/node/next'; const scalekit = new ScalekitClient( process.env.SCALEKIT_ENVIRONMENT_URL!, process.env.SCALEKIT_CLIENT_ID!, process.env.SCALEKIT_CLIENT_SECRET! ); export const auth = new ScalekitAuthNext({ client: scalekit, redirectUri: process.env.REDIRECT_URI!, cookieEncryptionSecret: process.env.COOKIE_ENCRYPTION_SECRET!, }); ``` app/login/route.ts ```typescript import { auth } from '../../lib/auth'; export const GET = auth.createLoginHandler(); ``` app/callback/route.ts ```typescript import { auth } from '../../lib/auth'; export const GET = auth.createCallbackHandler(); ``` app/logout/route.ts ```typescript import { auth } from '../../lib/auth'; export const GET = auth.createLogoutHandler(); ``` app/account/route.ts ```typescript import { auth } from '../../lib/auth'; export const GET = auth.withAuth(async (request, { user }) => { return Response.json({ sub: user?.sub }); }); ``` Open `http://localhost:3000/account`. A missing session returns **302** to `/login`, not a JSON 401. `user` is access-token claims. `sub` is always present. `email` appears only when you add it as a custom access-token claim. Pin runtime: 'nodejs' unless you use ScalekitEdgeClient `createMiddleware()` uses `ScalekitClient` by default. That client is Node-only. Export `runtime: 'nodejs'` in `middleware.ts`, or the Next.js build fails. See [`ScalekitEdgeClient`](#scalekitedgeclient) for Edge Runtime. ### constructor [Section titled “constructor”](#constructor) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### createLoginHandler [Section titled “createLoginHandler”](#createloginhandler) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### createCallbackHandler [Section titled “createCallbackHandler”](#createcallbackhandler) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### createLogoutHandler [Section titled “createLogoutHandler”](#createlogouthandler) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### withAuth [Section titled “withAuth”](#withauth) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### createMiddleware [Section titled “createMiddleware”](#createmiddleware) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### getSession [Section titled “getSession”](#getsession) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### currentUser [Section titled “currentUser”](#currentuser) classScalekitAuthNexthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/frameworks/nextjs.ts ### ScalekitEdgeClient [Section titled “ScalekitEdgeClient”](#scalekitedgeclient) classScalekitEdgeClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/edge.ts --- # DOCUMENT BOUNDARY --- # Authorization > Authorization helpers for protected resources Use auth helpers for authorization code exchange, token validation, and related login token flows on the Scalekit client. These methods sit next to session management—use them when implementing hosted login callbacks and token checks. ### updateLoginUserDetails [Section titled “updateLoginUserDetails”](#updateloginuserdetails) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/auth.ts --- # DOCUMENT BOUNDARY --- # Connections > Configure enterprise SSO connections Use the `connection` client to configure enterprise SSO (SAML/OIDC) for an organization. Enable SSO after the organization exists: create a connection, complete IdP setup, and test sign-in for that org. ### getConnection [Section titled “getConnection”](#getconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/connection.ts ### listConnectionsByDomain [Section titled “listConnectionsByDomain”](#listconnectionsbydomain) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/connection.ts ### listConnections [Section titled “listConnections”](#listconnections) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/connection.ts ### listAppConnections [Section titled “listAppConnections”](#listappconnections) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/connection.ts ### enableConnection [Section titled “enableConnection”](#enableconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/connection.ts ### disableConnection [Section titled “disableConnection”](#disableconnection) clientConnectionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/connection.ts --- # DOCUMENT BOUNDARY --- # Directory > Sync users and groups via SCIM directories Use the `directory` client for SCIM directory sync—listing providers, users, and groups provisioned from an IdP. Use this after SSO is in place when the customer provisions users via SCIM. ### listDirectories [Section titled “listDirectories”](#listdirectories) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts ### getDirectory [Section titled “getDirectory”](#getdirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts ### getPrimaryDirectoryByOrganizationId [Section titled “getPrimaryDirectoryByOrganizationId”](#getprimarydirectorybyorganizationid) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts ### listDirectoryUsers [Section titled “listDirectoryUsers”](#listdirectoryusers) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts ### listDirectoryGroups [Section titled “listDirectoryGroups”](#listdirectorygroups) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts ### enableDirectory [Section titled “enableDirectory”](#enabledirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts ### disableDirectory [Section titled “disableDirectory”](#disabledirectory) clientDirectorieshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/directory.ts --- # DOCUMENT BOUNDARY --- # Domains > Manage organization email domains Use the `domain` client to manage verified email domains for an organization (SSO routing and domain-based policies). Add a domain, complete verification, then use it with SSO and organization policies. ### createDomain [Section titled “createDomain”](#createdomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/domain.ts ### getDomain [Section titled “getDomain”](#getdomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/domain.ts ### listDomains [Section titled “listDomains”](#listdomains) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/domain.ts ### deleteDomain [Section titled “deleteDomain”](#deletedomain) clientDomainshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/domain.ts --- # DOCUMENT BOUNDARY --- # Organizations > Manage your customer organizations Use the `organization` client to create and manage customer tenants (organizations) in your Scalekit application. Start here when onboarding a new customer: create an organization, set external IDs and branding, then add users and SSO for that org. ### createOrganization [Section titled “createOrganization”](#createorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### listOrganization [Section titled “listOrganization”](#listorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### getOrganization [Section titled “getOrganization”](#getorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### getOrganizationByExternalId [Section titled “getOrganizationByExternalId”](#getorganizationbyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### updateOrganization [Section titled “updateOrganization”](#updateorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### updateOrganizationByExternalId [Section titled “updateOrganizationByExternalId”](#updateorganizationbyexternalid) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### deleteOrganization [Section titled “deleteOrganization”](#deleteorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### generatePortalLink [Section titled “generatePortalLink”](#generateportallink) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### updateOrganizationSettings [Section titled “updateOrganizationSettings”](#updateorganizationsettings) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### upsertUserManagementSettings [Section titled “upsertUserManagementSettings”](#upsertusermanagementsettings) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### searchOrganization [Section titled “searchOrganization”](#searchorganization) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### getOrganizationUserManagementSetting [Section titled “getOrganizationUserManagementSetting”](#getorganizationusermanagementsetting) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### updateOrganizationSessionPolicy [Section titled “updateOrganizationSessionPolicy”](#updateorganizationsessionpolicy) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts ### getOrganizationSessionPolicy [Section titled “getOrganizationSessionPolicy”](#getorganizationsessionpolicy) clientOrganizationshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/organization.ts --- # DOCUMENT BOUNDARY --- # Magic link & OTP > Send and verify passwordless login codes Use the `passwordless` client to send and verify email magic links or one-time codes for sign-in. Call send, then verify with the code or link token from the user’s email to complete login. ### sendPasswordlessEmail [Section titled “sendPasswordlessEmail”](#sendpasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/passwordless.ts ### verifyPasswordlessEmail [Section titled “verifyPasswordlessEmail”](#verifypasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/passwordless.ts ### resendPasswordlessEmail [Section titled “resendPasswordlessEmail”](#resendpasswordlessemail) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/passwordless.ts --- # DOCUMENT BOUNDARY --- # Permissions > Manage fine-grained permissions Use the `permission` client to define fine-grained permissions that roles can grant. Model permissions for resources in your app, then attach them to roles. ### createPermission [Section titled “createPermission”](#createpermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### getPermission [Section titled “getPermission”](#getpermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### listPermissions [Section titled “listPermissions”](#listpermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### updatePermission [Section titled “updatePermission”](#updatepermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### deletePermission [Section titled “deletePermission”](#deletepermission) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### listRolePermissions [Section titled “listRolePermissions”](#listrolepermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### addPermissionsToRole [Section titled “addPermissionsToRole”](#addpermissionstorole) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### removePermissionFromRole [Section titled “removePermissionFromRole”](#removepermissionfromrole) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts ### listEffectiveRolePermissions [Section titled “listEffectiveRolePermissions”](#listeffectiverolepermissions) clientPermissionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/permission.ts --- # DOCUMENT BOUNDARY --- # Resource consents > List and revoke the consents your end users grant against a resource When an end user allows an API client to act on their behalf against a resource, such as an MCP server, Scalekit records that grant as a consent. Use `scalekit.resources` to read those consents and revoke them from your own admin screens instead of the Scalekit dashboard. Each consent identifies the user by `externalUserId`—the identifier your application supplied when the consent was granted. The same audit and revoke actions are available in the dashboard under [Managing MCP clients](/authenticate/mcp/managing-mcp-clients/). ### listUserConsents [Section titled “listUserConsents”](#listuserconsents) classResourceClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/resource.ts ### revokeUserConsent [Section titled “revokeUserConsent”](#revokeuserconsent) classResourceClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/resource.ts --- # DOCUMENT BOUNDARY --- # Roles > Define and assign organization roles Use the `role` client to define organization roles and list role assignments. Create roles and permissions for authorization after you have organizations and users. ### createRole [Section titled “createRole”](#createrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### getRole [Section titled “getRole”](#getrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### listRoles [Section titled “listRoles”](#listroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### updateRole [Section titled “updateRole”](#updaterole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### deleteRole [Section titled “deleteRole”](#deleterole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### deleteRoleBase [Section titled “deleteRoleBase”](#deleterolebase) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### getRoleUsersCount [Section titled “getRoleUsersCount”](#getroleuserscount) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### createOrganizationRole [Section titled “createOrganizationRole”](#createorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### getOrganizationRole [Section titled “getOrganizationRole”](#getorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### listOrganizationRoles [Section titled “listOrganizationRoles”](#listorganizationroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### updateOrganizationRole [Section titled “updateOrganizationRole”](#updateorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### deleteOrganizationRole [Section titled “deleteOrganizationRole”](#deleteorganizationrole) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### getOrganizationRoleUsersCount [Section titled “getOrganizationRoleUsersCount”](#getorganizationroleuserscount) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### updateDefaultRoles [Section titled “updateDefaultRoles”](#updatedefaultroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### listDependentRoles [Section titled “listDependentRoles”](#listdependentroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### updateDefaultOrganizationRoles [Section titled “updateDefaultOrganizationRoles”](#updatedefaultorganizationroles) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts ### deleteOrganizationRoleBase [Section titled “deleteOrganizationRoleBase”](#deleteorganizationrolebase) clientRoleshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/role.ts --- # DOCUMENT BOUNDARY --- # Create client > Create the SDK client and run core auth helpers Create a `ScalekitClient` with your environment URL, client ID, and client secret. All other clients hang off this instance. Store credentials in environment variables. Never hard-code secrets. After you create the client, use [Sessions](/saaskit/sdks/node/sessions/) to validate tokens or open a domain client such as [Organizations](/saaskit/sdks/node/organizations/) or [Users](/saaskit/sdks/node/users/). ### validateAccessToken [Section titled “validateAccessToken”](#validateaccesstoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/scalekit.ts ### generateClientToken [Section titled “generateClientToken”](#generateclienttoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/scalekit.ts ### authenticateWithCode [Section titled “authenticateWithCode”](#authenticatewithcode) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/scalekit.ts ### getIdpInitiatedLoginClaims [Section titled “getIdpInitiatedLoginClaims”](#getidpinitiatedloginclaims) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/scalekit.ts ### refreshAccessToken [Section titled “refreshAccessToken”](#refreshaccesstoken) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/scalekit.ts --- # DOCUMENT BOUNDARY --- # Sessions > Validate tokens and manage user sessions Use the `session` client to inspect session metadata and revoke sessions when users sign out or you detect risk. Typical flows: load a session by ID after authentication, list a user’s sessions for a security UI, and revoke one session or all of a user’s sessions on logout. ### getSession [Section titled “getSession”](#getsession) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/session.ts ### getUserSessions [Section titled “getUserSessions”](#getusersessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/session.ts ### revokeSession [Section titled “revokeSession”](#revokesession) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/session.ts ### revokeAllUserSessions [Section titled “revokeAllUserSessions”](#revokeallusersessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/session.ts --- # DOCUMENT BOUNDARY --- # Users > Provision and manage users and memberships Use the `user` client to provision people, manage organization memberships, and assign roles. Common flows: invite or create a user, attach them to an organization, update profile fields, and look up users by Scalekit ID or your external ID. ### createUserAndMembership [Section titled “createUserAndMembership”](#createuserandmembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### getUser [Section titled “getUser”](#getuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### listUsers [Section titled “listUsers”](#listusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### updateUser [Section titled “updateUser”](#updateuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### deleteUser [Section titled “deleteUser”](#deleteuser) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### createMembership [Section titled “createMembership”](#createmembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### deleteMembership [Section titled “deleteMembership”](#deletemembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### updateMembership [Section titled “updateMembership”](#updatemembership) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### listOrganizationUsers [Section titled “listOrganizationUsers”](#listorganizationusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### resendInvite [Section titled “resendInvite”](#resendinvite) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### listUserRoles [Section titled “listUserRoles”](#listuserroles) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### listUserPermissions [Section titled “listUserPermissions”](#listuserpermissions) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### searchUsers [Section titled “searchUsers”](#searchusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### searchOrganizationUsers [Section titled “searchOrganizationUsers”](#searchorganizationusers) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### assignUserRoles [Section titled “assignUserRoles”](#assignuserroles) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### removeUserRole [Section titled “removeUserRole”](#removeuserrole) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### getUserByExternalId [Section titled “getUserByExternalId”](#getuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### updateUserByExternalId [Section titled “updateUserByExternalId”](#updateuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### deleteUserByExternalId [Section titled “deleteUserByExternalId”](#deleteuserbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### createMembershipByExternalId [Section titled “createMembershipByExternalId”](#createmembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### deleteMembershipByExternalId [Section titled “deleteMembershipByExternalId”](#deletemembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts ### updateMembershipByExternalId [Section titled “updateMembershipByExternalId”](#updatemembershipbyexternalid) clientUsershttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/user.ts --- # DOCUMENT BOUNDARY --- # Passkeys > Passkey and WebAuthn credentials Use the `webauthn` client to register and authenticate passkeys (WebAuthn credentials). Build registration and authentication ceremonies with the options and verification methods below. ### listCredentials [Section titled “listCredentials”](#listcredentials) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/webauthn.ts ### updateCredential [Section titled “updateCredential”](#updatecredential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/webauthn.ts ### deleteCredential [Section titled “deleteCredential”](#deletecredential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-node/blob/main/src/webauthn.ts --- # DOCUMENT BOUNDARY --- # Authorization > Authorization helpers for protected resources Use auth helpers for authorization code exchange, token validation, and related login token flows on the Scalekit client. These methods sit next to session management—use them when implementing hosted login callbacks and token checks. ### update\_login\_user\_details [Section titled “update\_login\_user\_details”](#update_login_user_details) clientAuthhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/auth.py --- # DOCUMENT BOUNDARY --- # Connected accounts > Connected accounts for agent workflows Manage connected accounts for agent tool access (AgentKit-style connections from the Python SaaSKit surface). Prefer the AgentKit SDK docs when building agent product flows; use these methods when integrating from the Python SaaS client. ### list\_connected\_accounts [Section titled “list\_connected\_accounts”](#list_connected_accounts) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### get\_connected\_account\_by\_identifier [Section titled “get\_connected\_account\_by\_identifier”](#get_connected_account_by_identifier) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### create\_connected\_account [Section titled “create\_connected\_account”](#create_connected_account) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### update\_connected\_account [Section titled “update\_connected\_account”](#update_connected_account) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### delete\_connected\_account [Section titled “delete\_connected\_account”](#delete_connected_account) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### get\_magic\_link\_for\_connected\_account [Section titled “get\_magic\_link\_for\_connected\_account”](#get_magic_link_for_connected_account) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### get\_connected\_account\_details\_by\_identifier [Section titled “get\_connected\_account\_details\_by\_identifier”](#get_connected_account_details_by_identifier) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py ### verify\_connected\_account\_user [Section titled “verify\_connected\_account\_user”](#verify_connected_account_user) clientConnectedAccountshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connected\_accounts.py --- # DOCUMENT BOUNDARY --- # Connections > Configure enterprise SSO connections Use `scalekit_client.connection` to configure enterprise SSO (SAML/OIDC) for an organization. Enable SSO after the organization exists: create a connection, complete IdP setup, and test sign-in for that org. ### list\_connections [Section titled “list\_connections”](#list_connections) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### list\_connections\_by\_domain [Section titled “list\_connections\_by\_domain”](#list_connections_by_domain) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### get\_connection [Section titled “get\_connection”](#get_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### create\_connection [Section titled “create\_connection”](#create_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### enable\_connection [Section titled “enable\_connection”](#enable_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### disable\_connection [Section titled “disable\_connection”](#disable_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### delete\_connection [Section titled “delete\_connection”](#delete_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### list\_app\_connections [Section titled “list\_app\_connections”](#list_app_connections) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### get\_environment\_connection [Section titled “get\_environment\_connection”](#get_environment_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### create\_environment\_connection [Section titled “create\_environment\_connection”](#create_environment_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py ### update\_environment\_connection [Section titled “update\_environment\_connection”](#update_environment_connection) clientConnectionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/connection.py --- # DOCUMENT BOUNDARY --- # Custom OAuth > Custom OAuth provider configuration Configure custom OAuth providers when you bring your own OAuth app outside the built-in connector catalog. Use this for providers Scalekit does not ship as a first-party connector. Supply client credentials and endpoints, then connect accounts through the usual OAuth flow. ### create\_custom\_provider [Section titled “create\_custom\_provider”](#create_custom_provider) clientCustomProvidershttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/providers.py ### update\_custom\_provider [Section titled “update\_custom\_provider”](#update_custom_provider) clientCustomProvidershttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/providers.py ### list\_providers [Section titled “list\_providers”](#list_providers) clientCustomProvidershttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/providers.py ### delete\_custom\_provider [Section titled “delete\_custom\_provider”](#delete_custom_provider) clientCustomProvidershttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/providers.py --- # DOCUMENT BOUNDARY --- # Directory > Sync users and groups via SCIM directories Use `scalekit_client.directory` for SCIM directory sync—listing providers, users, and groups provisioned from an IdP. Use this after SSO is in place when the customer provisions users via SCIM. ### list\_directories [Section titled “list\_directories”](#list_directories) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### get\_directory [Section titled “get\_directory”](#get_directory) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### create\_directory [Section titled “create\_directory”](#create_directory) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### list\_directory\_users [Section titled “list\_directory\_users”](#list_directory_users) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### list\_directory\_groups [Section titled “list\_directory\_groups”](#list_directory_groups) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### enable\_directory [Section titled “enable\_directory”](#enable_directory) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### disable\_directory [Section titled “disable\_directory”](#disable_directory) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### delete\_directory [Section titled “delete\_directory”](#delete_directory) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py ### get\_primary\_directory\_by\_organization\_id [Section titled “get\_primary\_directory\_by\_organization\_id”](#get_primary_directory_by_organization_id) clientDirectoryhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/directory.py --- # DOCUMENT BOUNDARY --- # Domains > Manage organization email domains Use `scalekit_client.domain` to manage verified email domains for an organization (SSO routing and domain-based policies). Add a domain, complete verification, then use it with SSO and organization policies. ### create\_domain [Section titled “create\_domain”](#create_domain) clientDomainhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/domain.py ### list\_domains [Section titled “list\_domains”](#list_domains) clientDomainhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/domain.py ### get\_domain [Section titled “get\_domain”](#get_domain) clientDomainhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/domain.py ### delete\_domain [Section titled “delete\_domain”](#delete_domain) clientDomainhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/domain.py --- # DOCUMENT BOUNDARY --- # M2M clients > Machine-to-machine clients and tokens Use the M2M client on `scalekit_client` to create and manage machine-to-machine OAuth clients and secrets for service-to-service auth. Create an M2M client, store the secret securely, then obtain tokens with client credentials. ### list\_organization\_clients [Section titled “list\_organization\_clients”](#list_organization_clients) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py ### get\_organization\_client [Section titled “get\_organization\_client”](#get_organization_client) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py ### create\_organization\_client [Section titled “create\_organization\_client”](#create_organization_client) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py ### update\_organization\_client [Section titled “update\_organization\_client”](#update_organization_client) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py ### delete\_organization\_client [Section titled “delete\_organization\_client”](#delete_organization_client) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py ### add\_organization\_client\_secret [Section titled “add\_organization\_client\_secret”](#add_organization_client_secret) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py ### remove\_organization\_client\_secret [Section titled “remove\_organization\_client\_secret”](#remove_organization_client_secret) clientM2MClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/m2m\_client.py --- # DOCUMENT BOUNDARY --- # Organizations > Manage your customer organizations Use `scalekit_client.organization` to create and manage customer tenants (organizations) in your Scalekit application. Start here when onboarding a new customer: create an organization, set external IDs and branding, then add users and SSO for that org. ### list\_organizations [Section titled “list\_organizations”](#list_organizations) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### create\_organization [Section titled “create\_organization”](#create_organization) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### get\_organization [Section titled “get\_organization”](#get_organization) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### get\_organization\_by\_external\_id [Section titled “get\_organization\_by\_external\_id”](#get_organization_by_external_id) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### update\_organization [Section titled “update\_organization”](#update_organization) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### delete\_organization [Section titled “delete\_organization”](#delete_organization) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### generate\_portal\_link [Section titled “generate\_portal\_link”](#generate_portal_link) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### update\_organization\_by\_external\_id [Section titled “update\_organization\_by\_external\_id”](#update_organization_by_external_id) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### update\_organization\_settings [Section titled “update\_organization\_settings”](#update_organization_settings) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### upsert\_user\_management\_settings [Section titled “upsert\_user\_management\_settings”](#upsert_user_management_settings) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### get\_organization\_session\_policy [Section titled “get\_organization\_session\_policy”](#get_organization_session_policy) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py ### update\_organization\_session\_policy [Section titled “update\_organization\_session\_policy”](#update_organization_session_policy) clientOrganizationhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/organization.py --- # DOCUMENT BOUNDARY --- # Magic link & OTP > Send and verify passwordless login codes Use `scalekit_client.passwordless` to send and verify email magic links or one-time codes for sign-in. Call send, then verify with the code or link token from the user’s email to complete login. ### send\_passwordless\_email [Section titled “send\_passwordless\_email”](#send_passwordless_email) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/passwordless.py ### verify\_passwordless\_email [Section titled “verify\_passwordless\_email”](#verify_passwordless_email) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/passwordless.py ### resend\_passwordless\_email [Section titled “resend\_passwordless\_email”](#resend_passwordless_email) clientPasswordlesshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/passwordless.py --- # DOCUMENT BOUNDARY --- # Permissions > Manage fine-grained permissions Use `scalekit_client.permissions` to define fine-grained permissions that roles can grant. Model permissions for resources in your app, then attach them to roles. ### list\_permissions [Section titled “list\_permissions”](#list_permissions) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### get\_permission [Section titled “get\_permission”](#get_permission) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### create\_permission [Section titled “create\_permission”](#create_permission) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### update\_permission [Section titled “update\_permission”](#update_permission) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### delete\_permission [Section titled “delete\_permission”](#delete_permission) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### list\_role\_permissions [Section titled “list\_role\_permissions”](#list_role_permissions) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### add\_permissions\_to\_role [Section titled “add\_permissions\_to\_role”](#add_permissions_to_role) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### remove\_permission\_from\_role [Section titled “remove\_permission\_from\_role”](#remove_permission_from_role) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py ### list\_effective\_role\_permissions [Section titled “list\_effective\_role\_permissions”](#list_effective_role_permissions) clientPermissionhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/permissions.py --- # DOCUMENT BOUNDARY --- # Roles > Define and assign organization roles Use `scalekit_client.roles` to define organization roles and list role assignments. Create roles and permissions for authorization after you have organizations and users. ### list\_roles [Section titled “list\_roles”](#list_roles) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### get\_role [Section titled “get\_role”](#get_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### create\_role [Section titled “create\_role”](#create_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### update\_role [Section titled “update\_role”](#update_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### delete\_role [Section titled “delete\_role”](#delete_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### get\_role\_users\_count [Section titled “get\_role\_users\_count”](#get_role_users_count) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### list\_organization\_roles [Section titled “list\_organization\_roles”](#list_organization_roles) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### create\_organization\_role [Section titled “create\_organization\_role”](#create_organization_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### get\_organization\_role [Section titled “get\_organization\_role”](#get_organization_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### update\_organization\_role [Section titled “update\_organization\_role”](#update_organization_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### delete\_organization\_role [Section titled “delete\_organization\_role”](#delete_organization_role) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### delete\_role\_base [Section titled “delete\_role\_base”](#delete_role_base) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### get\_organization\_role\_users\_count [Section titled “get\_organization\_role\_users\_count”](#get_organization_role_users_count) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### update\_default\_organization\_roles [Section titled “update\_default\_organization\_roles”](#update_default_organization_roles) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### delete\_organization\_role\_base [Section titled “delete\_organization\_role\_base”](#delete_organization_role_base) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### update\_default\_roles [Section titled “update\_default\_roles”](#update_default_roles) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py ### list\_dependent\_roles [Section titled “list\_dependent\_roles”](#list_dependent_roles) clientRolehttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/role.py --- # DOCUMENT BOUNDARY --- # Create client > Create the SDK client and run core auth helpers Create a `ScalekitClient` with your environment URL, client ID, and client secret. All other clients hang off this instance. Store credentials in environment variables. Never hard-code secrets. After you create the client, use [Sessions](/saaskit/sdks/python/sessions/) to work with sessions or open a domain client such as [Organizations](/saaskit/sdks/python/organization/) or [Users](/saaskit/sdks/python/user/). ### get\_authorization\_url [Section titled “get\_authorization\_url”](#get_authorization_url) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### authenticate\_with\_code [Section titled “authenticate\_with\_code”](#authenticate_with_code) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### get\_idp\_initiated\_login\_claims [Section titled “get\_idp\_initiated\_login\_claims”](#get_idp_initiated_login_claims) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### validate\_access\_token [Section titled “validate\_access\_token”](#validate_access_token) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### get\_logout\_url [Section titled “get\_logout\_url”](#get_logout_url) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### verify\_webhook\_payload [Section titled “verify\_webhook\_payload”](#verify_webhook_payload) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### refresh\_access\_token [Section titled “refresh\_access\_token”](#refresh_access_token) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### generate\_client\_token [Section titled “generate\_client\_token”](#generate_client_token) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### get\_client\_access\_token [Section titled “get\_client\_access\_token”](#get_client_access_token) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### validate\_access\_token\_and\_get\_claims [Section titled “validate\_access\_token\_and\_get\_claims”](#validate_access_token_and_get_claims) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### validate\_token [Section titled “validate\_token”](#validate_token) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### verify\_scopes [Section titled “verify\_scopes”](#verify_scopes) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py ### verify\_interceptor\_payload [Section titled “verify\_interceptor\_payload”](#verify_interceptor_payload) classScalekitClienthttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/client.py --- # DOCUMENT BOUNDARY --- # Sessions > Validate tokens and manage user sessions Use the `scalekit_client.sessions` client to inspect session metadata and revoke sessions when users sign out or you detect risk. Typical flows: load a session by ID after authentication, list a user’s sessions for a security UI, and revoke one session or all of a user’s sessions on logout. ### get\_session [Section titled “get\_session”](#get_session) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/sessions.py ### get\_user\_sessions [Section titled “get\_user\_sessions”](#get_user_sessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/sessions.py ### revoke\_session [Section titled “revoke\_session”](#revoke_session) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/sessions.py ### revoke\_all\_user\_sessions [Section titled “revoke\_all\_user\_sessions”](#revoke_all_user_sessions) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/sessions.py ### create\_session\_filter [Section titled “create\_session\_filter”](#create_session_filter) clientSessionshttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/sessions.py --- # DOCUMENT BOUNDARY --- # Users > Provision and manage users and memberships Use `scalekit_client.users` to provision people, manage organization memberships, and assign roles. Common flows: invite or create a user, attach them to an organization, update profile fields, and look up users by Scalekit ID or your external ID. ### list\_users [Section titled “list\_users”](#list_users) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### list\_organization\_users [Section titled “list\_organization\_users”](#list_organization_users) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### get\_user [Section titled “get\_user”](#get_user) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### get\_user\_by\_external\_id [Section titled “get\_user\_by\_external\_id”](#get_user_by_external_id) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### create\_user\_and\_membership [Section titled “create\_user\_and\_membership”](#create_user_and_membership) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### update\_user [Section titled “update\_user”](#update_user) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### delete\_user [Section titled “delete\_user”](#delete_user) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### create\_membership [Section titled “create\_membership”](#create_membership) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### update\_membership [Section titled “update\_membership”](#update_membership) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### delete\_membership [Section titled “delete\_membership”](#delete_membership) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### resend\_invite [Section titled “resend\_invite”](#resend_invite) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### update\_user\_by\_external\_id [Section titled “update\_user\_by\_external\_id”](#update_user_by_external_id) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### delete\_user\_by\_external\_id [Section titled “delete\_user\_by\_external\_id”](#delete_user_by_external_id) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### create\_membership\_by\_external\_id [Section titled “create\_membership\_by\_external\_id”](#create_membership_by_external_id) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### update\_membership\_by\_external\_id [Section titled “update\_membership\_by\_external\_id”](#update_membership_by_external_id) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### delete\_membership\_by\_external\_id [Section titled “delete\_membership\_by\_external\_id”](#delete_membership_by_external_id) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### list\_user\_roles [Section titled “list\_user\_roles”](#list_user_roles) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py ### list\_user\_permissions [Section titled “list\_user\_permissions”](#list_user_permissions) clientUserhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/users.py --- # DOCUMENT BOUNDARY --- # Passkeys > Passkey and WebAuthn credentials Use `scalekit_client.webauthn` to register and authenticate passkeys (WebAuthn credentials). Build registration and authentication ceremonies with the options and verification methods below. ### list\_credentials [Section titled “list\_credentials”](#list_credentials) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/webauthn.py ### update\_credential [Section titled “update\_credential”](#update_credential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/webauthn.py ### delete\_credential [Section titled “delete\_credential”](#delete_credential) clientWebAuthnhttps\://github.com/scalekit-inc/scalekit-sdk-python/blob/main/scalekit/webauthn.py --- # DOCUMENT BOUNDARY --- # Configure Scalekit > Complete values.yaml examples and field reference for a self-hosted Scalekit deployment. You will review example values.yaml files and the complete field reference to configure your self-hosted Scalekit deployment. This helps you understand exactly what values the setup script will generate and how to customize them for external databases or production settings. ## Example values.yaml files [Section titled “Example values.yaml files”](#example-valuesyaml-files) These examples show the full structure of a generated `values.yaml`. The setup script produces this file automatically. Refer here when reviewing or modifying values after initial setup. * Quick start (subcharts) Use this configuration to get Scalekit running quickly without provisioning external PostgreSQL or Redis. Setting `secrets.create: true` lets the chart create all required Kubernetes secrets from values in this file. No `kubectl` secret commands are needed. **Do not use this in production.** The bundled databases have no backups, no replication, and no persistent storage guarantees. See the [quick start guide](/self-hosted/quickstart/) for a step-by-step walkthrough. values.yaml (quick start) ```yaml 1 scalekit: 2 config: 3 app: 4 domain: "" 5 seedData: 6 adminUser: 7 firstName: "" 8 lastName: "" 9 email: "" 10 emailServer: 11 settings: 12 fromEmail: "hi@" 13 fromName: "Team " 14 host: "" 15 port: 16 username: "" 17 18 postgresql: 19 enabled: true 20 21 redis: 22 enabled: true 23 24 secrets: 25 create: true 26 svix: 27 jwtSecret: "" 28 apiToken: "" 29 registry: 30 password: "" 31 32 gateway: 33 enabled: true 34 provider: "" # gcp for GKE; other for all other clusters 35 className: "" 36 annotations: 37 : "" 38 redirectToHttps: true 39 healthCheckPolicy: 40 enabled: true # GKE only ``` * Production (external services) Use this configuration for production deployments with external PostgreSQL and Redis that you manage. values.yaml (production) ```yaml 1 scalekit: 2 config: 3 app: 4 domain: "auth.example.com" # your domain, without scheme or trailing slash 5 protocol: "https" 6 region: "us" # us or eu — set once, do not change after first install 7 8 database: 9 host: "pg.internal.example.com" 10 name: "scalekit" 11 user: "scalekit" 12 port: 5432 13 # Password is stored in the authentication-secret Kubernetes secret 14 15 redis: 16 host: "redis.internal.example.com" 17 port: 6379 18 db: 0 19 # Password is stored in the authentication-secret Kubernetes secret 20 21 seedData: 22 adminUser: 23 firstName: "Admin" 24 lastName: "User" 25 email: "admin@example.com" 26 emailServer: 27 serverType: "SMTP" 28 provider: "POSTMARK" # POSTMARK, SENDGRID, or OTHER 29 enabled: true 30 settings: 31 fromEmail: "noreply@example.com" 32 fromName: "Your Company" 33 host: "smtp.postmarkapp.com" 34 port: 587 35 username: "your-smtp-api-key" 36 37 # External services — disable subcharts 38 postgresql: 39 enabled: false 40 41 redis: 42 enabled: false 43 44 gateway: 45 enabled: true 46 className: "gke-l7-global-external-managed" # your GatewayClass 47 provider: "gcp" # "gcp" for GKE Gateway; "other" (or omit) for most other clusters / ingress controllers 48 redirectToHttps: true 49 healthCheckPolicy: 50 enabled: true # GKE only ``` *** ## Field reference [Section titled “Field reference”](#field-reference) ### App [Section titled “App”](#app) ```yaml 1 scalekit: 2 config: 3 app: 4 domain: "auth.example.com" 5 protocol: "https" 6 region: "us" ``` | Field | Description | | ---------- | ------------------------------------------------------------------------------------------------- | | `domain` | Base domain for your Scalekit instance. Must match your gateway hostname. | | `protocol` | Use `https` in production. For local HTTP dev, set to `http` and add `oidc.allow_insecure: true`. | | `region` | Data residency context. Set once. Do not change after the initial install. | ### Database [Section titled “Database”](#database) ```yaml 1 scalekit: 2 config: 3 database: 4 host: "your-db-host" 5 name: "scalekit" 6 user: "scalekit" 7 port: 5432 ``` When using external PostgreSQL (`postgresql.enabled: false`), the database password is injected via Kubernetes secret: * **`secrets.create: true`**: provide it under `secrets.database.password` in `values.yaml`; the chart creates the secret automatically * **`secrets.create: false`**: pre-create the `authentication-secret` with a `database_password` key using the setup script Omit this section entirely when using the bundled PostgreSQL subchart (`postgresql.enabled: true`). ### Redis [Section titled “Redis”](#redis) ```yaml 1 scalekit: 2 config: 3 redis: 4 host: "your-redis-host" 5 port: 6379 6 db: 0 ``` When using external Redis (`redis.enabled: false`), the Redis password and DSN are injected via Kubernetes secret: * **`secrets.create: true`**: provide the DSN under `secrets.svix.redisDsn` in `values.yaml`; the chart creates the secret automatically * **`secrets.create: false`**: pre-create the `svix-secrets` with a `redis-dsn` key using the setup script Omit this section entirely when using the bundled Redis subchart (`redis.enabled: true`). ### Seed data [Section titled “Seed data”](#seed-data) Seed data is applied once on first install. It creates the initial admin user and configures the email server. ```yaml 1 scalekit: 2 config: 3 seedData: 4 adminUser: 5 firstName: "Admin" 6 lastName: "User" 7 email: "admin@example.com" 8 emailServer: 9 serverType: "SMTP" 10 provider: "POSTMARK" # POSTMARK, SENDGRID, or OTHER 11 enabled: true 12 settings: 13 fromEmail: "noreply@example.com" 14 fromName: "Your Company" 15 host: "smtp.postmarkapp.com" 16 port: 587 17 username: "your-smtp-api-key-or-username" ``` ### Gateway [Section titled “Gateway”](#gateway) Scalekit uses the Kubernetes Gateway API for ingress. ```yaml 1 gateway: 2 enabled: true 3 className: "gke-l7-global-external-managed" 4 provider: "gcp" 5 redirectToHttps: true 6 healthCheckPolicy: 7 enabled: true # GKE only ``` Set `gateway.className` to the GatewayClass for your cluster: | Provider | GatewayClass | | -------------- | ---------------------------------- | | GKE (external) | `gke-l7-global-external-managed` | | GKE (internal) | `gke-l7-regional-internal-managed` | | Istio | `istio` | | Envoy Gateway | `eg` | Set `provider: "gcp"` for GKE. It enables GKE-specific resources like `HealthCheckPolicy`. Set `provider: "other"` for all other clusters. ## Gateway annotations [Section titled “Gateway annotations”](#gateway-annotations) Annotations on the Gateway resource are how you attach TLS certificates and configure provider-specific behavior. Add them under `gateway.annotations` in your `values.yaml`: ```yaml 1 gateway: 2 annotations: 3 : "" ``` Common annotations by provider: | Provider | Annotation | Purpose | | -------------------------- | -------------------------------- | ------------------------------------------------- | | GKE | `networking.gke.io/certmap` | Attach a GCP Certificate Manager cert map for TLS | | cert-manager (any cluster) | `cert-manager.io/cluster-issuer` | Provision TLS via cert-manager | | AWS (ALB) | `kubernetes.io/ingress.class` | Route through an ALB | ### Example: GCP Certificate Manager [Section titled “Example: GCP Certificate Manager”](#example-gcp-certificate-manager) ```yaml 1 gateway: 2 enabled: true 3 className: "gke-l7-global-external-managed" 4 provider: "gcp" 5 annotations: 6 networking.gke.io/certmap: "scalekit-cert-map" 7 redirectToHttps: true 8 healthCheckPolicy: 9 enabled: true ``` ## Optional components [Section titled “Optional components”](#optional-components) ### OpenFGA (fine-grained authorization) [Section titled “OpenFGA (fine-grained authorization)”](#openfga-fine-grained-authorization) OpenFGA is disabled by default. Enable it when you need fine-grained authorization at scale: ```yaml 1 sidecars: 2 openfga: 3 enabled: true ``` OpenFGA requires its own PostgreSQL database (`openfga`). Credentials are stored in the `openfga-secrets` Kubernetes secret. ### Directory server (SCIM) [Section titled “Directory server (SCIM)”](#directory-server-scim) SCIM provisioning is disabled by default: ```yaml 1 scalekit: 2 config: 3 directoryServer: 4 enabled: true ``` ## Secrets reference [Section titled “Secrets reference”](#secrets-reference) Scalekit uses Kubernetes secrets to inject all sensitive values into pods. There are two ways these secrets are created: * **`secrets.create: true`** (quick start): the chart auto-creates all secrets from values you provide in `values.yaml` under the `secrets.*` block * **`secrets.create: false`** (full deployment): you pre-create the secrets using the setup script | Secret name | Key fields | Created by | | ------------------------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | `authentication-service-token` | `TOKEN`: dashboard auth token | Chart or setup script | | `db-migrations` | `DATABASE_URL`, `DB_ADAPTER` | Chart or setup script | | `authentication-secret` | DB password, Redis password, OIDC keys, cookie keys, email keys, webhook API key | Chart or setup script | | `svix-secrets` | `db-dsn`, `jwt-secret`, `main-secret`, `redis-dsn`, `api-token` | Chart or setup script | | `artifact-registry-secret` | Docker registry credentials for the Scalekit container registry | Chart or setup script | | `openfga-secrets` | `keys`, `uri` | Chart or setup script. Only when `sidecars.openfga.enabled: true`. | Next, Setup script will generate the values.yaml and all required Kubernetes secrets for you. --- # DOCUMENT BOUNDARY --- # Install Scalekit > Deploy Scalekit on a Kubernetes cluster using Helm and the Gateway API. You will deploy Scalekit on any Kubernetes cluster using the Helm chart from the distribution portal and the Kubernetes Gateway API for ingress. This helps you complete a production installation with external PostgreSQL, Redis, and properly managed secrets. 1. ### Create a personal access token [Section titled “Create a personal access token”](#create-a-personal-access-token) Log in to the Scalekit distribution portal. This token authenticates your cluster to pull both the Helm chart and container images from the Scalekit container registry. ![Scalekit distribution portal login](/.netlify/images?url=_astro%2Fportal-login.Ch1RHBxb.png\&w=1248\&h=1220\&dpl=6aaa70ad2ea7b40008ad2afd) After signing in you will see the portal home page. ![Scalekit distribution portal home](/.netlify/images?url=_astro%2Fportal-home.DCD46C0C.png\&w=3016\&h=750\&dpl=6aaa70ad2ea7b40008ad2afd) Click the **profile icon** in the top-right corner. ![Profile icon in the top-right corner](/.netlify/images?url=_astro%2Fportal-profile-icon.12S91tKZ.png\&w=176\&h=118\&dpl=6aaa70ad2ea7b40008ad2afd) In the dropdown, select **Personal Access Tokens**. ![Profile dropdown menu with Personal Access Tokens option](/.netlify/images?url=_astro%2Fportal-profile-menu.B7Y57Dda.png\&w=458\&h=540\&dpl=6aaa70ad2ea7b40008ad2afd) You will see the Personal Access Tokens page. Click **+ Create token**. ![Personal Access Tokens page](/.netlify/images?url=_astro%2Fportal-pat-list.CVQyTrNz.png\&w=3012\&h=632\&dpl=6aaa70ad2ea7b40008ad2afd) A form slides in. Enter a **Label** and set an **Expires At** date, then click **+ Create**. ![Create a Personal Access Token form](/.netlify/images?url=_astro%2Fportal-pat-form.BTN9MgDu.png\&w=654\&h=602\&dpl=6aaa70ad2ea7b40008ad2afd) Your token is displayed once — **copy it immediately.** It cannot be retrieved after you leave this page. Note the expiry date and rotate before it lapses; a lapsed token causes `ImagePullBackOff` on new deployments and upgrades. ![Token displayed after creation: copy it now](/.netlify/images?url=_astro%2Fportal-pat-created.Dm1iZXeP.png\&w=2250\&h=544\&dpl=6aaa70ad2ea7b40008ad2afd) 2. ### Run the setup script [Section titled “Run the setup script”](#run-the-setup-script) The [setup script](/self-hosted/setup-script/) collects your configuration interactively and generates two files: a secrets script and a `values.yaml`. Copy the script from that page, then run it: ```bash 1 chmod +x setup-secrets.sh 2 bash setup-secrets.sh ``` When prompted for environment, select the option that matches your target: * **1. Minikube** (local, uses nginx ingress) * **2. GCP / GKE** (configures GKE Gateway and NEG annotations) * **3. Other Kubernetes cluster** (generic config, add your own ingress) * **4. Evaluation** (bundled PostgreSQL and Redis; minimal setup) The script walks you through namespace, PostgreSQL, Redis, SMTP, registry token, domain, and admin user settings. GKE-specific Gateway settings are only collected for option `2`. When the script finishes, it prints the paths to two generated files. Before proceeding, open each file and verify the values are correct. **`values-gke-.yaml`**: confirm: * `app.domain` matches your intended domain * `database.host`, `database.name`, and `database.user` point to the right PostgreSQL instance * `redis.host` points to the right Redis instance * `seedData.adminUser.email` is the address you want for the initial admin login * `gateway.className` and `gateway.annotations` match your cluster’s gateway configuration **`scalekit-secrets-gke-.sh`**: confirm: * The namespace at the top matches your intended namespace * Database and Redis connection strings in `db-migrations` and `authentication-secret` are correct * The registry token in `artifact-registry-secret` is the one you just created 3. ### Apply the Kubernetes secrets [Section titled “Apply the Kubernetes secrets”](#apply-the-kubernetes-secrets) Run the secrets script the setup script generated: ```bash 1 bash scalekit-secrets-gke-.sh ``` Set the namespace (defaults to the value used in the setup script): ```bash 1 # Set once for your deployment 2 NAMESPACE=${NAMESPACE:-scalekit} ``` Verify all secrets were created: ```bash 1 kubectl get secrets -n ${NAMESPACE} ``` Expected secrets: `authentication-service-token`, `db-migrations`, `authentication-secret`, `svix-secrets`, `artifact-registry-secret`. If you ran the script with `--enable-openfga`, `openfga-secrets` will also be present. 4. ### Create a deployment [Section titled “Create a deployment”](#create-a-deployment) Deployments are created through the Scalekit distribution portal. #### Open Deployments [Section titled “Open Deployments”](#open-deployments) In the left sidebar, click **Deployments**, then click **+ New Deployment** in the top-right corner. ![Deployments page](/.netlify/images?url=_astro%2Fportal-deployments.B4-mDB4x.png\&w=3018\&h=652\&dpl=6aaa70ad2ea7b40008ad2afd) #### Select the application [Section titled “Select the application”](#select-the-application) In the **Create New Deployment** dialog, select **Scalekit Onprem** and click **Continue**. ![Create New Deployment: select Scalekit Onprem](/.netlify/images?url=_astro%2Fportal-new-deployment.Bw77r62a.png\&w=1422\&h=1136\&dpl=6aaa70ad2ea7b40008ad2afd) #### Configure the deployment [Section titled “Configure the deployment”](#configure-the-deployment) ![Deployment Configuration form](/.netlify/images?url=_astro%2Fportal-deployment-config.C-spEDWY.png\&w=1314\&h=1208\&dpl=6aaa70ad2ea7b40008ad2afd) * **Deployment Name**: any name you choose; `scalekit` is recommended * **Kubernetes Namespace**: must match the namespace you used in step 3 * Leave **Enable cluster-scoped permissions** checked * Leave **Set custom resource requirements for the Distr agent** unchecked Click **Continue**. #### Select a version and add values [Section titled “Select a version and add values”](#select-a-version-and-add-values) ![Application Configuration form](/.netlify/images?url=_astro%2Fportal-app-config.Ca5o-m3n.png\&w=1292\&h=1276\&dpl=6aaa70ad2ea7b40008ad2afd) * **Version**: select the latest available version from the dropdown * **Helm release name**: leave as `scalekit` or set your own * **Helm values**: paste the full contents of `values-gke-.yaml` generated by the setup script Click **Create Deployment**. The portal moves to the **Deploy** step and shows a `kubectl apply` command. #### Connect your cluster [Section titled “Connect your cluster”](#connect-your-cluster) The portal shows a **Deployment Created Successfully** screen with a `kubectl apply` command. ![Deployment created successfully: copy the kubectl command](/.netlify/images?url=_astro%2Fportal-deploy-success.EdEl6go6.png\&w=1892\&h=1282\&dpl=6aaa70ad2ea7b40008ad2afd) Click **Copy Command** and run it on your cluster: ```bash 1 kubectl apply -n ${NAMESPACE} -f "" ``` Databases must exist before connecting The deployment triggers database migrations on connect. If any of the three PostgreSQL databases (`scalekit`, `webhooks`, `openfga`) do not exist, the migration will fail. The setup script prints the exact `CREATE DATABASE` commands to run if needed. 5. ### Update DNS [Section titled “Update DNS”](#update-dns) Once the Gateway is up, get its external IP: ```bash 1 kubectl get gateway -n ${NAMESPACE} ``` Copy the external IP from the `ADDRESS` column. In your DNS provider, create a wildcard `A` record pointing to it: ```plaintext 1 *. ``` DNS propagation can take a few minutes. You can verify with: ```bash 1 dig app. ``` 6. ### Verify the deployment [Section titled “Verify the deployment”](#verify-the-deployment) ```bash 1 kubectl get pods -n ${NAMESPACE} ``` All pods should show `Running` status. Open the admin dashboard at `https://app.` and sign in with the admin credentials you provided during setup. Next, Upgrades and maintenance will help you update to new versions through the portal and handle routine tasks like certificate renewal. --- # DOCUMENT BOUNDARY --- # Secrets setup script > Interactive script that generates all Kubernetes secrets and a values.yaml for your Scalekit deployment. You will run a one-time interactive script that generates all Kubernetes secrets and a values.yaml file for your deployment. This helps you bootstrap correctly without manually creating secrets or making copy-paste errors in configuration. The script is a **one-time tool for initial deployment**. Run it once to bootstrap your cluster. Do not run it again on an existing installation. It collects your configuration interactively and produces two output files: * **A secrets script** (`scalekit-secrets--.sh`): runs `kubectl` commands to create all five required Kubernetes secrets * **A values file** (`values--.yaml`): paste this into the Scalekit distribution portal when creating your deployment ## Prerequisites [Section titled “Prerequisites”](#prerequisites) | Tool | Version | Purpose | | --------- | ------------------ | ------------------------------------------- | | `bash` | 4.0 or later | Run the script | | `openssl` | Any modern version | Generate cryptographic keys and tokens | | `python3` | 3.6 or later | Generate webhook JWT and OIDC client secret | | `kubectl` | 1.27 or later | Create Kubernetes secrets in your cluster | `kubectl` must be configured and pointed at the cluster you are deploying to before you run the script. On macOS, `bash` ships as version 3. Install a newer version with Homebrew: ```bash 1 brew install bash ``` ## Run the setup script [Section titled “Run the setup script”](#run-the-setup-script) Run this script only once The script auto-generates cryptographic keys (OIDC master key, cookie encryption keys, webhook JWT secret, and others). These are written into your Kubernetes secrets and used by the running system. If you run the script again, it generates different values and overwrites the secrets, which will break your existing deployment. To update a single credential (for example, to rotate a database password), edit the specific Kubernetes secret directly rather than re-running the script. Copy the script below, save it as `setup-secrets.sh`, make it executable, then run it: ```bash 1 chmod +x setup-secrets.sh 2 bash setup-secrets.sh ``` When prompted to choose an environment, enter the number that matches your target: | Option | Environment | Notes | | ------ | ------------------------ | ----------------------------------------------------------------------------------------------------- | | `1` | Minikube (local) | Uses nginx ingress; sets `http` protocol and `allow_insecure: true` | | `2` | GCP / GKE | Configures GKE Gateway API and NEG annotations | | `3` | Other Kubernetes cluster | Generic config. You add your own ingress or gateway. | | `4` | Evaluation | Fast path: Helm spins up bundled PostgreSQL and Redis; only asks for webhook and registry credentials | ### Evaluation mode [Section titled “Evaluation mode”](#evaluation-mode) Option `4` is a shortcut for a local or throwaway environment. The script asks only for a webhook JWT secret, a webhook API token, and a registry access token, then exits. It generates a minimal `values-eval-.yaml` to paste into the distribution portal. No databases or Redis instances are needed. The chart provides bundled ones. **Do not use evaluation mode in production.** The bundled databases have no backups, no replication, and no persistent storage guarantees. ### Optional flags [Section titled “Optional flags”](#optional-flags) | Flag | Effect | | ------------------- | ------------------------------------------------------------------------------------ | | `--enable-openfga` | Includes OpenFGA secrets and database configuration | | `--change-defaults` | Prompts you to confirm or override default values instead of accepting them silently | ## What the script collects [Section titled “What the script collects”](#what-the-script-collects) ### Full setup (options 1, 2, 3) [Section titled “Full setup (options 1, 2, 3)”](#full-setup-options-1-2-3) The script walks through these sections: | Section | What it asks | | ---------------------- | ------------------------------------------------------------------------------------ | | **Namespace** | Kubernetes namespace to deploy into | | **Environment** | Deployment target: Minikube, GCP/GKE, other K8s, or Evaluation | | **PostgreSQL** | Host, port, credentials, and database names (scalekit, webhooks, openfga if enabled) | | **Redis** | Host, port, password, and db indexes for app, background jobs, and webhooks | | **Email (SMTP)** | From address, host, port, username, and password | | **Container registry** | Registry token and server URL from the Scalekit distribution portal | | **GKE Gateway** | GatewayClass name and GCP certificate map (GCP/GKE only) | | **App settings** | Domain, region, replica count | | **Admin user** | First name, last name, email for the initial dashboard login | All cryptographic values (OIDC keys, cookie keys, webhook JWT, etc.) are auto-generated. You do not supply these. ### Evaluation mode (option 4) [Section titled “Evaluation mode (option 4)”](#evaluation-mode-option-4) The script only asks for: | Section | What it asks | | ----------------------- | ----------------------------------- | | **Namespace** | Kubernetes namespace to deploy into | | **Webhook credentials** | JWT secret and API token | | **Container registry** | Registry access token | ## After the script completes [Section titled “After the script completes”](#after-the-script-completes) The script prints the paths to both generated files. Before proceeding: 1. Run the secrets script to create all Kubernetes secrets: ```bash 1 bash scalekit-secrets--.sh ``` 2. Paste the contents of `values--.yaml` into the Scalekit distribution portal when creating or updating your deployment. See [Install Scalekit](/self-hosted/installation/) for the full portal flow. Check databases exist first The script reminds you to verify that all three PostgreSQL databases exist before connecting your cluster. The migration hook will fail if any database is missing. ## Script [Section titled “Script”](#script) setup-secrets.sh ```bash 1 #!/usr/bin/env bash 2 set -euo pipefail 3 4 # ── Arguments ───────────────────────────────────────────────────────────────── 5 # Usage: bash setup-secrets.sh [--enable-openfga] [--change-defaults] 6 OPENFGA_ENABLED="false" 7 CHANGE_DEFAULTS="false" 8 for arg in "$@"; do 9 case "$arg" in 10 --enable-openfga) OPENFGA_ENABLED="true" ;; 11 --change-defaults) CHANGE_DEFAULTS="true" ;; 12 *) echo "Unknown argument: $arg"; exit 1 ;; 13 esac 14 done 15 16 # ── Colours ────────────────────────────────────────────────────────────────── 17 BOLD=$'\033[1m' 18 DIM=$'\033[2m' 19 RED=$'\033[31m' 20 GREEN=$'\033[32m' 21 YELLOW=$'\033[33m' 22 CYAN=$'\033[36m' 23 RESET=$'\033[0m' 24 25 header() { echo "\n${BOLD}${CYAN}▶ $*${RESET}"; } 26 prompt() { echo "${YELLOW}$*${RESET}"; } 27 success() { echo "${GREEN}✓ $*${RESET}"; } 28 dim() { echo "${DIM}$*${RESET}"; } 29 30 ask() { 31 local var="$1" msg="$2" default="${3:-}" 32 # If a default exists and --change-defaults is not set, use it silently 33 if [[ -n "$default" && "$CHANGE_DEFAULTS" == "false" ]]; then 34 eval "$var=\"$default\"" 35 dim " $msg = $default (default)" 36 return 37 fi 38 while true; do 39 if [[ -n "$default" ]]; then 40 read -rp "${YELLOW}$msg [${default}]: ${RESET}" input 41 else 42 read -rp "${YELLOW}$msg: ${RESET}" input 43 fi 44 if [[ -z "$input" && -n "$default" ]]; then 45 eval "$var=\"$default\"" 46 break 47 elif [[ -n "$input" ]]; then 48 eval "$var=\"$input\"" 49 break 50 else 51 echo "${RED} ✗ This field is required. Please enter a value.${RESET}" 52 fi 53 done 54 } 55 56 ask_secret() { 57 local var="$1" msg="$2" default="${3:-}" 58 # If the 3rd argument was explicitly passed (even as ""), empty input is allowed 59 local allow_empty="${3+yes}" 60 while true; do 61 if [[ -n "$default" ]]; then 62 read -rp "${YELLOW}$msg [${default}]: ${RESET}" input 63 else 64 read -rp "${YELLOW}$msg: ${RESET}" input 65 fi 66 if [[ -z "$input" && -n "$default" ]]; then 67 eval "$var=\"$default\"" 68 break 69 elif [[ -z "$input" && "$allow_empty" == "yes" ]]; then 70 eval "$var=\"\"" 71 break 72 elif [[ -n "$input" ]]; then 73 eval "$var=\"$input\"" 74 break 75 else 76 echo "${RED} ✗ This field is required. Please enter a value.${RESET}" 77 fi 78 done 79 } 80 81 # ── Step 1: Namespace & environment ────────────────────────────────────────── 82 header "Step 1 — Namespace & environment" 83 ask NAMESPACE "Kubernetes namespace to deploy Scalekit into" 84 echo 85 echo -e "${YELLOW}Which environment are you deploying to?${RESET}" 86 echo " 1) Minikube (local)" 87 echo " 2) GCP / GKE" 88 echo " 3) Other Kubernetes cluster" 89 echo " 4) Evaluation (quickstart — Helm brings up PostgreSQL & Redis)" 90 read -rp "${YELLOW}Enter 1, 2, 3 or 4: ${RESET}" ENV_CHOICE 91 if [[ "$ENV_CHOICE" == "1" ]]; then 92 ENV_LABEL="minikube" 93 elif [[ "$ENV_CHOICE" == "2" ]]; then 94 ENV_LABEL="gke" 95 elif [[ "$ENV_CHOICE" == "4" ]]; then 96 ENV_LABEL="eval" 97 else 98 ENV_LABEL="k8s" 99 fi 100 101 # ── Evaluation flow (early exit) ────────────────────────────────────────────── 102 if [[ "$ENV_CHOICE" == "4" ]]; then 103 header "Step 2 — Evaluation setup" 104 dim " Helm will spin up PostgreSQL and Redis automatically." 105 dim " You only need a Svix API token and registry credentials." 106 echo 107 108 ask_secret SVIX_JWT_SECRET " Svix JWT secret (must be the secret used to sign the API token)" 109 ask_secret SVIX_API_KEY " Svix API token (JWT signed with the above secret)" 110 ask_secret REGISTRY_PASSWORD " Registry access token" 111 echo 112 113 VALUES_FILE="$(pwd)/values-eval-$(date +%Y%m%d%H%M%S).yaml" 114 cat > "$VALUES_FILE" <}" 391 echo " redis.db (main) = $REDIS_DB" 392 echo " redis.db (asynq) = $ASYNQ_REDIS_DB" 393 echo " redis.db (svix) = $SVIX_REDIS_DB → $SVIX_REDIS_DSN" 394 echo " email_key = na (fixed)" 395 echo " smtp password = $SMTP_PASSWORD" 396 echo " sendgrid_key = na (fixed)" 397 echo " smtp from = $EMAIL_FROM_NAME <$EMAIL_FROM>" 398 echo " smtp host:port = $SMTP_HOST:$SMTP_PORT" 399 echo " smtp username = $SMTP_USERNAME" 400 echo " app.domain = $APP_DOMAIN" 401 echo " app.region = $APP_REGION" 402 echo " app.protocol = $APP_PROTOCOL" 403 echo " replicaCount = $REPLICA_COUNT" 404 echo " adminUser = $ADMIN_FIRST_NAME $ADMIN_LAST_NAME <$ADMIN_EMAIL>" 405 echo " registry_server = $REGISTRY_SERVER" 406 echo " registry_password = $REGISTRY_PASSWORD" 407 echo 408 409 # ── Step 6: Write secrets script ───────────────────────────────────────────── 410 OUTPUT_FILE="$(pwd)/scalekit-secrets-${ENV_LABEL}-$(date +%Y%m%d%H%M%S).sh" 411 412 cat > "$OUTPUT_FILE" <> "$OUTPUT_FILE" < "$VALUES_FILE" < "$VALUES_FILE" < "$VALUES_FILE" <> /etc/hosts'" 764 echo 765 dim " Or add manually — open /etc/hosts and append this line:" 766 echo " 127.0.0.1 app.${APP_DOMAIN} auth.${APP_DOMAIN}" 767 echo 768 dim " 5. Update CoreDNS so pods inside the cluster can resolve app.${APP_DOMAIN} and auth.${APP_DOMAIN}:" 769 echo 770 dim " Open the CoreDNS ConfigMap and find the IP already assigned to host.minikube.internal." 771 dim " Add two more entries pointing to that same IP:" 772 echo 773 echo " kubectl edit configmap coredns -n kube-system" 774 echo 775 echo " # Inside the hosts { } block, add:" 776 echo " app.${APP_DOMAIN}" 777 echo " auth.${APP_DOMAIN}" 778 echo 779 dim " Then restart CoreDNS to apply:" 780 echo " kubectl rollout restart deployment coredns -n kube-system" 781 echo 782 echo "${BOLD}${CYAN}└─────────────────────────────────────────────────────────────┘${RESET}" 783 fi ``` Once both files are on disk, you have everything needed to install Scalekit. Next, [Installation](/self-hosted/installation/) covers applying the secrets script and creating the deployment through the portal. --- # DOCUMENT BOUNDARY --- # System requirements > Kubernetes, database, and network requirements for a self-hosted Scalekit deployment. You will confirm that your Kubernetes cluster, databases, and network meet the requirements for a self-hosted deployment. This helps you avoid installation failures and costly production issues later. ## Prepare Kubernetes [Section titled “Prepare Kubernetes”](#prepare-kubernetes) | Requirement | Value | | ------------------ | ------------------------------ | | Kubernetes version | 1.27 or later | | Helm version | 3.12 or later | | `kubectl` | Configured with cluster access | Any managed Kubernetes service works (GKE, EKS, AKS, or a self-managed cluster). Scalekit supports two ingress options. Use one, not both: * **Kubernetes Gateway API** (recommended for cloud clusters): requires a GatewayClass installed on your cluster * **Nginx Ingress** (for local or Minikube deployments): requires the nginx ingress controller For Gateway API, common GatewayClasses: | Provider | GatewayClass | | ------------- | ------------------------------------------- | | GKE | `gke-l7-global-external-managed` (built-in) | | Istio | `istio` | | Envoy Gateway | `eg` | On GKE, the Gateway controller is enabled by default. For other clusters, install the Gateway API CRDs and a compatible controller before deploying Scalekit. ## Prepare PostgreSQL [Section titled “Prepare PostgreSQL”](#prepare-postgresql) Scalekit requires **three separate databases** on PostgreSQL 15 or later. These can all live on the same PostgreSQL instance. | Database | Used by | | ---------- | --------------------------------- | | `scalekit` | Core auth service | | `webhooks` | Webhook delivery | | `openfga` | Authorization engine (if enabled) | Create a dedicated user with full privileges on each database. Scalekit runs migrations automatically on install and upgrade. ## Prepare Redis [Section titled “Prepare Redis”](#prepare-redis) | Requirement | Value | | ----------- | ------------ | | Version | 6.2 or later | Scalekit uses Redis for session storage, token caching, and background job queues. Redis does not need persistence enabled, but enabling RDB snapshots is recommended for production. ## Set up email (SMTP) [Section titled “Set up email (SMTP)”](#set-up-email-smtp) Scalekit sends transactional email for password resets, magic links, and user invitations. You need an SMTP provider configured before first run. Supported providers with first-class integration: **Postmark**, **SendGrid**. Any SMTP server works with the `OTHER` provider type. ## Size your nodes [Section titled “Size your nodes”](#size-your-nodes) | Resource | Production (per node) | | -------- | --------------------- | | CPU | 4 vCPUs | | RAM | 8 GB | The Scalekit Deployment defaults to 2 replicas with autoscaling up to 20. Each replica includes all sidecar containers. Tune `replicaCount` and HPA settings in your `values.yaml`. ## Configure network and DNS [Section titled “Configure network and DNS”](#configure-network-and-dns) ### Set up DNS [Section titled “Set up DNS”](#set-up-dns) A wildcard DNS record pointing to your Gateway’s external IP is required. You set this up after the deployment is running (see [Install Scalekit](/self-hosted/installation/#update-dns)). ### Set up TLS [Section titled “Set up TLS”](#set-up-tls) HTTPS is required. Manage certificates through your cloud provider’s certificate manager (for example, GCP Certificate Manager) and reference it via a Gateway annotation. cert-manager is also supported. Add the appropriate annotation to `gateway.annotations` in your `values.yaml`. ## Access the container registry [Section titled “Access the container registry”](#access-the-container-registry) Scalekit container images are hosted on a private container registry. You receive the registry server URL and credentials through the Scalekit distribution portal as part of onboarding. The registry token is stored as a Kubernetes image pull secret (`artifact-registry-secret`) during setup. ## Next step [Section titled “Next step”](#next-step) Once your infrastructure is ready, the Configure your deployment page will help you prepare the values.yaml that drives your deployment. --- # DOCUMENT BOUNDARY --- # Troubleshooting > Diagnose and fix common issues with a self-hosted Scalekit deployment on Kubernetes. This guide helps you diagnose and resolve common issues when running Scalekit on your own Kubernetes cluster. Start with the quick diagnostics, then use the symptom/cause/solution sections below to fix specific problems. ## Quick diagnostics [Section titled “Quick diagnostics”](#quick-diagnostics) Before investigating specific errors, run these basic checks to identify which pods are unhealthy and gather initial diagnostics. ### Check pod status [Section titled “Check pod status”](#check-pod-status) Set the namespace (the setup script defaults to `scalekit`): ```bash 1 # Set once for your deployment 2 NAMESPACE=${NAMESPACE:-scalekit} ``` ```bash 1 kubectl get pods -n ${NAMESPACE} 2 kubectl describe pod -n ${NAMESPACE} 3 kubectl logs -n ${NAMESPACE} --tail=100 ``` For the main Scalekit pod (multiple containers), specify the container: ```bash 1 # Main auth service 2 kubectl logs -n ${NAMESPACE} -c scalekit --tail=100 3 4 # Dashboard 5 kubectl logs -n ${NAMESPACE} -c dashboard --tail=100 6 7 # Svix (webhooks) 8 kubectl logs -n ${NAMESPACE} -c svix --tail=100 ``` ## Helm deployment issues [Section titled “Helm deployment issues”](#helm-deployment-issues) ### `ImagePullBackOff` or `ErrImagePull` [Section titled “ImagePullBackOff or ErrImagePull”](#imagepullbackoff-or-errimagepull) **Symptom:** Pods fail to start with `ImagePullBackOff` or `ErrImagePull`. **Cause:** The cluster cannot pull images from the Scalekit container registry. This is almost always caused by a missing or expired registry secret. **Solution:** 1. Confirm the secret exists: ```bash 1 kubectl get secret artifact-registry-secret -n ${NAMESPACE} ``` 2. If it is missing, recreate it: ```bash 1 kubectl create secret docker-registry artifact-registry-secret \ 2 --docker-server= \ 3 --docker-username=oauth2accesstoken \ 4 --docker-password= \ 5 -n ${NAMESPACE} ``` 3. Verify your registry token has not expired. Tokens from the distribution portal are time-limited. Token expiry breaks image pulls When the token expires, new deployments and upgrades will fail with `ImagePullBackOff`. Set a reminder to renew it before it lapses. ### Migration hook fails or times out [Section titled “Migration hook fails or times out”](#migration-hook-fails-or-times-out) **Symptom:** The `db-migrations` job fails or the Helm install hangs on the pre-install hook. **Cause:** The migration job cannot connect to PostgreSQL (wrong connection string, database does not exist, or network issue). **Solution:** 1. Check the job logs: ```bash 1 kubectl get jobs -n ${NAMESPACE} 2 kubectl logs job/scalekit-db-migrations -n ${NAMESPACE} ``` 2. Verify the `DATABASE_URL` secret is correct and points to a reachable PostgreSQL instance. 3. Ensure the target databases (`scalekit`, `webhooks`, `openfga`) exist and the database user has full privileges. ### Pod stuck in `CrashLoopBackOff` [Section titled “Pod stuck in CrashLoopBackOff”](#pod-stuck-in-crashloopbackoff) **Symptom:** The main Scalekit pod keeps crashing and restarting. **Cause:** A required secret is missing or a configuration value (hostnames, domains, credentials) is incorrect. **Solution:** 1. Check the previous container logs for the exact error: ```bash 1 kubectl logs -n ${NAMESPACE} -c scalekit --previous ``` 2. Common causes: * Missing keys in `authentication-secret` → Re-run `bash setup-secrets.sh` * `database.host` or `redis.host` unreachable → Verify connectivity and values in `values.yaml` * `domain` does not match your gateway hostname → Correct `values.yaml` and re-apply 3. Once the cause is fixed, delete the pod (or the whole release) so Kubernetes restarts it with the updated configuration. ## Gateway and ingress issues [Section titled “Gateway and ingress issues”](#gateway-and-ingress-issues) ### Gateway has no external IP [Section titled “Gateway has no external IP”](#gateway-has-no-external-ip) **Symptom:** `kubectl get gateway` shows no address or the Gateway stays in a pending state. **Cause:** The GatewayClass is missing, or the Gateway controller (e.g. GKE Gateway) is not running in the cluster. **Solution:** 1. Inspect the Gateway: ```bash 1 kubectl get gateway -n ${NAMESPACE} 2 kubectl describe gateway scalekit -n ${NAMESPACE} ``` 2. Verify a matching GatewayClass exists: ```bash 1 kubectl get gatewayclass ``` 3. Ensure `gateway.className` in your `values.yaml` exactly matches the installed GatewayClass name. ## Getting help [Section titled “Getting help”](#getting-help) If the issue is not covered here, gather the following information before contacting support: * **Namespace**: The Kubernetes namespace where Scalekit is deployed * **Error messages**: Full output from `kubectl logs`, `kubectl describe`, and Helm output * **Pod status**: Output of `kubectl get pods -n ${NAMESPACE}` * **Values used**: Relevant sections from your `values.yaml` (redact secrets) * **Steps to reproduce**: What you were doing when the issue occurred * **Environment**: Local (Minikube), GKE, or other cluster ### Support channels [Section titled “Support channels”](#support-channels) * **Documentation**: Review the [quickstart](/self-hosted/quickstart/), [installation](/self-hosted/installation/), and [configuration](/self-hosted/configuration/) guides * **Community**: Join the [#ask-anything channel on Slack](https://join.slack.com/t/scalekit-community/shared_invite/zt-3gsxwr4hc-0tvhwT2b_qgVSIZQBQCWRw) (the Scalekit Community workspace) * **Support**: Submit a ticket through your Scalekit dashboard or contact for production issues ## Next steps [Section titled “Next steps”](#next-steps) * [Upgrades and maintenance](/self-hosted/upgrades/) * [Configuration reference](/self-hosted/configuration/) --- # DOCUMENT BOUNDARY --- # Upgrades and maintenance > How to upgrade your self-hosted Scalekit deployment and perform routine maintenance tasks. You will upgrade your self-hosted Scalekit deployment and perform routine maintenance using the portal and Helm. This helps you adopt new versions safely, roll back if needed, and keep TLS and secrets current without disrupting service. ## Upgrade Scalekit [Section titled “Upgrade Scalekit”](#upgrade-scalekit) New versions are available through the Scalekit distribution portal. Upgrades are performed through the portal. The deployment agent running in your cluster picks up the change and applies it automatically. Database migrations run before the new pods start. 1. ### Select the new version in the portal [Section titled “Select the new version in the portal”](#select-the-new-version-in-the-portal) Log in to the Scalekit distribution portal. In the left sidebar, click **Deployments** and select your deployment. * Click **Edit deployment** * Under **Version**, select the new version * Click **Update deployment** The portal notifies the deployment agent in your cluster. No manual `kubectl` command is needed. 2. ### Monitor the upgrade [Section titled “Monitor the upgrade”](#monitor-the-upgrade) The deployment agent handles chart delivery and migration sequencing. Check its logs to follow progress: ```bash 1 kubectl logs -l app=distr-agent -n --tail=100 -f ``` 3. ### Verify the upgrade [Section titled “Verify the upgrade”](#verify-the-upgrade) ```bash 1 kubectl get pods -n 2 kubectl rollout status deployment/scalekit -n ``` ## Roll back an upgrade [Section titled “Roll back an upgrade”](#roll-back-an-upgrade) If an upgrade causes issues, roll back using Helm: ```bash 1 # List revisions 2 helm history scalekit -n 3 4 # Roll back to the previous revision 5 helm rollback scalekit -n ``` ## Renew TLS certificates [Section titled “Renew TLS certificates”](#renew-tls-certificates) TLS certificates are managed through your cloud provider’s certificate manager (for example, GCP Certificate Manager) or cert-manager. Renew certificates through your provider. The gateway picks up the updated certificate automatically without restarting Scalekit. ## Routine maintenance tasks [Section titled “Routine maintenance tasks”](#routine-maintenance-tasks) | Task | Frequency | Action | | ------------------------- | ------------- | --------------------------------------------------------------------------------- | | Review auth logs | Daily | Admin dashboard → **Audit logs** | | Check pod health | Daily | `kubectl get pods -n ` | | Rotate Redis cache | As needed | Automatic. Expired keys are evicted by Redis TTL. | | Back up databases | Regular | Take consistent backups of your PostgreSQL databases | | Rotate registry token | Before expiry | Create a new token in the portal, update `artifact-registry-secret`, restart pods | | Rotate individual secrets | Per policy | Edit the specific Kubernetes secret directly and restart pods | Next, Troubleshooting will help you diagnose and fix the most common problems you may encounter after deployment. --- # DOCUMENT BOUNDARY --- # Ways to implement SSO logins > Implement single sign-on on your login page using three UX strategies: identifier-driven, SSO button, or organization-specific pages. Single sign-on (SSO) login requires careful UX design to balance enterprise authentication requirements with user experience. Your login page must accommodate both SSO users (who authenticate through their organization’s identity provider) and non-SSO users (who use passwords or social authentication). This guide presents three proven UX strategies for adding SSO to your login page. Each strategy offers different trade-offs between user experience, implementation complexity, and administrative control. Choose the approach that best fits your users’ needs and your application’s architecture. The right strategy depends on your user base: identifier-driven flows work best when admins control authentication methods, explicit SSO buttons give users choice, and organization-specific login pages simplify enterprise deployments. ![Login page with password and social auth methods](/.netlify/images?url=_astro%2Fsimple_login_page.CjjjVgoK.png\&w=1024\&h=1222\&dpl=6aaa70ad2ea7b40008ad2afd) ## Strategy 1: Identifier-driven single sign-on [Section titled “Strategy 1: Identifier-driven single sign-on”](#strategy-1-identifier-driven-single-sign-on) Collect the user’s email address first. Use the email domain or organization identifier to determine whether to route to SSO or password-based authentication. ![Identifier-driven login](/.netlify/images?url=_astro%2Fidentifier_first_login.BlfaJ4QS.png\&w=2222\&h=1044\&dpl=6aaa70ad2ea7b40008ad2afd) Users don’t choose the authentication method. This reduces cognitive load and works well when admins mandate SSO after users have already logged in with passwords. Popular products like [Google](https://accounts.google.com), [Microsoft](https://login.microsoftonline.com), and [AWS](https://console.aws.amazon.com/console/) use this strategy. ## Strategy 2: Login with single sign-on button [Section titled “Strategy 2: Login with single sign-on button”](#strategy-2-login-with-single-sign-on-button) Add a “Login with SSO” button to your login page. This presents all authentication options and lets users choose their preferred method. ![Explicit option for login with SSO](/.netlify/images?url=_astro%2Fsso_button_login.onnUOag1.png\&w=1082\&h=1242\&dpl=6aaa70ad2ea7b40008ad2afd) If a user attempts password login but their admin mandates SSO, force SSO-based authentication instead of showing an error. Popular products like [Cal.com](https://app.cal.com/auth/login) and [Notion](https://www.notion.so/login) use this strategy. ## Strategy 3: organization-specific login page [Section titled “Strategy 3: organization-specific login page”](#strategy-3-organization-specific-login-page) Serve different login pages for each organization instead of a single login page. For example, `https://customer1.b2b-app.com/login` and `https://customer2.b2b-app.com/login`. Show only the authentication methods applicable to that organization based on the URL. Popular products like [Zendesk](https://www.zendesk.com/in/login/) and [Slack](https://scalekit.slack.com/) use this strategy. The drawback is that users must remember their organization URL to access the login page. *** ## Next steps [Section titled “Next steps”](#next-steps) After implementing your chosen SSO login strategy: * [Pre-check SSO by domain](/guides/user-auth/check-sso-domain/) - Validate email domains have active SSO before redirecting * [Complete login with code exchange](/authenticate/fsa/complete-login/) - Exchange authorization codes for user data and tokens * [Manage user sessions](/authenticate/fsa/manage-session/) - Store and validate session tokens securely --- # DOCUMENT BOUNDARY --- # Authorization URL to initiate SSO > Learn how to construct and implement authorization URLs in Scalekit to initiate secure Single Sign-on (SSO) flows with your identity provider. The authorization endpoint is where your application redirects users to begin the authentication process. Scalekit powers this endpoint and handles redirecting users to the appropriate identity provider. Example authorization URL ```sh https://SCALEKIT_ENVIRONMENT_URL/oauth/authorize? response_type=code& client_id=skc_1234& scope=openid%20profile& redirect_uri=https%3A%2F%2Fyoursaas.com%2Fcallback& organization_id=org_1243412& state=aHR0cHM6Ly95b3Vyc2Fhcy5jb20vZGVlcGxpbms%3D ``` ## Parameters [Section titled “Parameters”](#parameters) | Parameter | Requirement | Description | | ----------------- | ----------- | -------------------------------------------------------------------------------------------------------------------- | | `client_id` | Required | Your unique client identifier from the API credentials page | | `nonce` | Optional | Random value for replay protection | | `organization_id` | Required\* | Identifier for the organization initiating SSO | | `connection_id` | Required\* | Identifier for the specific SSO connection | | `domain` | Required\* | Domain portion of email addresses configured for an organization | | `provider` | Required\* | Social login provider name. Supported providers: `google`, `microsoft`, `github`, `gitlab`, `linkedin`, `salesforce` | | `response_type` | Required | Must be set to `code` | | `redirect_uri` | Required | URL where Scalekit sends the response. Must match an authorized redirect URI | | `scope` | Required | Must be set to `openid email profile` | | `state` | Optional | Opaque string for request-response correlation | | `login_hint` | Optional | User’s email address for prefilling the login form | \* You must provide one of `organization_id`, `connection_id`, `domain`, or `provider`. If you identify SSO connection using `domain` or `login_hint`, the domain must be registered to the organization. Register domains in **Dashboard > Organizations > General**, or let customers add them via the admin portal. See [Onboard enterprise customers](/sso/guides/onboard-enterprise-customers/). ## SDK usage [Section titled “SDK usage”](#sdk-usage) Use Scalekit SDKs to generate authorization URLs programmatically. This approach handles parameter encoding and validation automatically. * Node.js ```diff 1 import { ScalekitClient } from '@scalekit-sdk/node'; 2 3 const scalekit = new ScalekitClient( 4 'https://your-subdomain.scalekit.dev', 5 '', 6 '' 7 ); 8 9 const options = { 10 loginHint: 'user@example.com', 11 organizationId: 'org_123235245', 12 }; 13 14 +const authorizationURL = scalekit.getAuthorizationUrl(redirectUri, options); 15 // Example generated URL: 16 // https://your-subdomain.scalekit.dev/oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile&redirect_uri=https%3A%2F%2Fyoursaas.com%2Fcallback&organization_id=org_123235245&login_hint=user%40example.com&state=abc123 ``` * Python ```diff 1 from scalekit import ScalekitClient, AuthorizationUrlOptions 2 3 scalekit = ScalekitClient( 4 'https://your-subdomain.scalekit.dev', 5 '', 6 '' 7 ) 8 9 options = AuthorizationUrlOptions() 10 options.organization_id = "org_12345" 11 options.login_hint = "user@example.com" 12 13 authorization_url = scalekit.get_authorization_url( 14 + redirect_uri, 15 + options 16 +) 17 +# Example generated URL: 18 # https://your-subdomain.scalekit.dev/oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile&redirect_uri=https%3A%2F%2Fyoursaas.com%2Fcallback&organization_id=org_12345&login_hint=user%40example.com&state=abc123 ``` * Go ```diff 1 import ( 2 "github.com/scalekit-inc/scalekit-sdk-go" 3 ) 4 5 func main() { 6 scalekitClient := scalekit.NewScalekitClient( 7 "https://your-subdomain.scalekit.dev", 8 "", 9 "" 10 ) 11 12 options := scalekitClient.AuthorizationUrlOptions{ 13 OrganizationId: "org_12345", 14 LoginHint: "user@example.com", 15 } 16 17 +authorizationURL := scalekitClient.GetAuthorizationUrl( 18 +redirectUrl, 19 +options, 20 + ) 21 // Example generated URL: 22 // https://your-subdomain.scalekit.dev/oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile&redirect_uri=https%3A%2F%2Fyoursaas.com%2Fcallback&organization_id=org_12345&login_hint=user%40example.com&state=abc123 23 } ``` * Java ```diff 1 package com.scalekit; 2 3 import com.scalekit.ScalekitClient; 4 import com.scalekit.internal.http.AuthorizationUrlOptions; 5 6 public class Main { 7 public static void main(String[] args) { 8 ScalekitClient scalekitClient = new ScalekitClient( 9 "https://your-subdomain.scalekit.dev", 10 "", 11 "" 12 ); 13 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 14 // Option 1: Authorization URL with the organization ID 15 options.setOrganizationId("org_13388706786312310"); 16 // Option 2: Authorization URL with the connection ID 17 options.setConnectionId("con_13388706786312310"); 18 // Option 3: Authorization URL with login hint 19 options.setLoginHint("user@example.com"); 20 21 try { 22 +String url = scalekitClient.authentication().getAuthorizationUrl(redirectUrl, options).toString(); 23 // Example generated URL: 24 // https://your-subdomain.scalekit.dev/oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile&redirect_uri=https%3A%2F%2Fyoursaas.com%2Fcallback&organization_id=org_13388706786312310&connection_id=con_13388706786312310&login_hint=user%40example.com&state=abc123 25 } catch (Exception e) { 26 System.out.println(e.getMessage()); 27 } 28 } 29 } ``` ## Parameter precedence [Section titled “Parameter precedence”](#parameter-precedence) When you provide multiple connection parameters, Scalekit follows a specific precedence order to determine which identity provider to use: 1. `provider` (highest precedence): If present, Scalekit ignores all other connection parameters and directs users to the specified social login provider. For example, `provider=google` redirects users to Google’s login screen. See [Social Login](/authenticate/auth-methods/social-logins/) for more details. 2. `connection_id`: Takes highest precedence among enterprise SSO parameters. Scalekit uses this specific connection if you provide a valid connection ID. If the connection ID is invalid, the authorization request fails. 3. `organization_id`: Scalekit uses this parameter when no valid `connection_id` is provided. It selects the SSO connection configured for the specified organization. 4. `domain`: Scalekit uses this parameter when neither `connection_id` nor `organization_id` are provided. It selects the SSO connection configured for the specified domain. 5. `login_hint` (lowest precedence): Scalekit extracts the domain portion from the email address and uses the corresponding SSO connection mapped to that organization. The domain must be registered to the organization either manually from the Scalekit Dashboard or through the admin portal when [onboarding an enterprise customer](/sso/guides/onboard-enterprise-customers/). ## Common scenarios [Section titled “Common scenarios”](#common-scenarios) --- # DOCUMENT BOUNDARY --- # Handle identity provider initiated SSO > Learn how to securely implement IdP-initiated Single Sign-On for your application This guide shows you how to securely implement Identity Provider (IdP)-initiated Single Sign-On for your application. When users log into your application directly from their identity provider’s portal, Scalekit converts the IdP-initiated request to a Service Provider (SP)-initiated flow for enhanced security. The workflow converts the traditional IdP-initiated flow to a secure SP-initiated flow by: 1. The user logs into their identity provider portal and selects your application 2. The identity provider sends user details as assertions to Scalekit 3. Scalekit redirects to your initiate login endpoint with a JWT token 4. Your application validates the JWT and generates a new SP-initiated authorization URL To securely implement IdP-initiated SSO, follow these steps to convert incoming IdP-initiated requests to SP-initiated flows: 1. Set up an initiate login endpoint and register it in **Dashboard > Developers > Redirect URLs > Initiate Login URL** 2. Extract information from the JWT token containing organization, connection, and user details 3. Convert to SP-initiated flow using the extracted parameters to generate a new authorization URL 4. Handle errors with proper callback processing and error handling best practices ## Implementation examples [Section titled “Implementation examples”](#implementation-examples) Use the extracted parameters to initiate a new SSO request. This converts the IdP-initiated flow to a secure SP-initiated flow. Here are implementation examples: * Node.js Express.js ```javascript 1 // Security: ALWAYS verify requests are from Scalekit before processing 2 // This prevents unauthorized parties from triggering your interceptor logic 3 4 // Use case: Handle IdP-initiated SSO requests from enterprise customer portals 5 // Examples: Okta dashboard, Azure AD portal, Google Workspace apps 6 7 const express = require('express'); 8 const app = express(); 9 10 app.get('/login', async (req, res) => { 11 try { 12 // Your Initiate Login Endpoint receives a JWT 13 const { error_description, idp_initiated_login } = req.query; 14 15 if (error_description) { 16 return res.redirect('/login?error=auth_failed'); 17 } 18 19 // Decode the JWT and extract claims 20 if (idp_initiated_login) { 21 const { 22 connection_id, 23 organization_id, 24 login_hint, 25 relay_state 26 } = await scalekit.getIdpInitiatedLoginClaims(idp_initiated_login); 27 28 // Use ONE of the following properties for authorization 29 const options = {}; 30 if (connection_id) options.connectionId = connection_id; 31 if (organization_id) options.organizationId = organization_id; 32 if (login_hint) options.loginHint = login_hint; 33 if (relay_state) options.state = relay_state; 34 35 // Generate Authorization URL for SP-initiated flow 36 const url = scalekit.getAuthorizationUrl( 37 process.env.REDIRECT_URI, 38 options 39 ); 40 41 return res.redirect(url); 42 } 43 44 // Handle regular login flow here 45 res.redirect('/login'); 46 } catch (error) { 47 console.error('IdP-initiated login error:', error); 48 res.redirect('/login?error=auth_failed'); 49 } 50 }); ``` * Python Flask ```python 1 # Security: ALWAYS verify requests are from Scalekit before processing 2 # This prevents unauthorized parties from triggering your interceptor logic 3 4 # Use case: Handle IdP-initiated SSO requests from enterprise customer portals 5 # Examples: Okta dashboard, Azure AD portal, Google Workspace apps 6 7 from flask import Flask, request, redirect, url_for 8 import os 9 10 app = Flask(__name__) 11 12 @app.route('/login') 13 def login(): 14 try: 15 # Your Initiate Login Endpoint receives a JWT 16 error_description = request.args.get('error_description') 17 idp_initiated_login = request.args.get('idp_initiated_login') 18 19 if error_description: 20 return redirect(url_for('login', error='auth_failed')) 21 22 # Decode the JWT and extract claims 23 if idp_initiated_login: 24 claims = await scalekit_client.get_idp_initiated_login_claims(idp_initiated_login) 25 26 # Extract claims with fallbacks 27 connection_id = claims.get('connection_id') 28 organization_id = claims.get('organization_id') 29 login_hint = claims.get('login_hint') 30 relay_state = claims.get('relay_state') 31 32 # Create authorization options 33 options = AuthorizationUrlOptions() 34 if connection_id: 35 options.connection_id = connection_id 36 if organization_id: 37 options.organization_id = organization_id 38 if login_hint: 39 options.login_hint = login_hint 40 if relay_state: 41 options.state = relay_state 42 43 # Generate Authorization URL for SP-initiated flow 44 authorization_url = scalekit_client.get_authorization_url( 45 redirect_uri=os.getenv('REDIRECT_URI'), 46 options=options 47 ) 48 49 return redirect(authorization_url) 50 51 # Handle regular login flow here 52 return redirect(url_for('login')) 53 except Exception as error: 54 print(f"IdP-initiated login error: {error}") 55 return redirect(url_for('login', error='auth_failed')) ``` * Go Gin ```go 1 // Security: ALWAYS verify requests are from Scalekit before processing 2 // This prevents unauthorized parties from triggering your interceptor logic 3 4 // Use case: Handle IdP-initiated SSO requests from enterprise customer portals 5 // Examples: Okta dashboard, Azure AD portal, Google Workspace apps 6 7 package main 8 9 import ( 10 "net/http" 11 "github.com/gin-gonic/gin" 12 ) 13 14 func (a *App) handleLogin(c *gin.Context) { 15 // Your Initiate Login Endpoint receives a JWT 16 errDescription := c.Query("error_description") 17 idpInitiatedLogin := c.Query("idp_initiated_login") 18 19 if errDescription != "" { 20 c.Redirect(http.StatusFound, "/login?error=auth_failed") 21 return 22 } 23 24 // Decode the JWT and extract claims 25 if idpInitiatedLogin != "" { 26 claims, err := scalekitClient.GetIdpInitiatedLoginClaims(c.Request.Context(), idpInitiatedLogin) 27 if err != nil { 28 http.Error(c.Writer, err.Error(), http.StatusInternalServerError) 29 return 30 } 31 32 // Create authorization options with ONE of the following properties 33 options := scalekit.AuthorizationUrlOptions{} 34 if claims.ConnectionID != "" { 35 options.ConnectionId = claims.ConnectionID 36 } 37 if claims.OrganizationID != "" { 38 options.OrganizationId = claims.OrganizationID 39 } 40 if claims.LoginHint != "" { 41 options.LoginHint = claims.LoginHint 42 } 43 if claims.RelayState != "" { 44 options.State = claims.RelayState 45 } 46 47 // Generate Authorization URL for SP-initiated flow 48 authUrl, err := scalekitClient.GetAuthorizationUrl(redirectUrl, options) 49 if err != nil { 50 http.Error(c.Writer, err.Error(), http.StatusInternalServerError) 51 return 52 } 53 54 c.Redirect(http.StatusFound, authUrl.String()) 55 return 56 } 57 58 // Handle regular login flow here 59 c.Redirect(http.StatusFound, "/login") 60 } ``` * Java Spring Boot ```java 1 // Security: ALWAYS verify requests are from Scalekit before processing 2 // This prevents unauthorized parties from triggering your interceptor logic 3 4 // Use case: Handle IdP-initiated SSO requests from enterprise customer portals 5 // Examples: Okta dashboard, Azure AD portal, Google Workspace apps 6 7 import org.springframework.web.bind.annotation.*; 8 import org.springframework.web.servlet.view.RedirectView; 9 import javax.servlet.http.HttpServletResponse; 10 11 @RestController 12 public class AuthController { 13 14 @GetMapping("/login") 15 public RedirectView handleLogin( 16 @RequestParam(required = false, name = "error_description") String errorDescription, 17 @RequestParam(required = false, name = "idp_initiated_login") String idpInitiatedLoginToken, 18 HttpServletResponse response) throws IOException { 19 20 if (errorDescription != null) { 21 return new RedirectView("/login?error=auth_failed"); 22 } 23 24 // Decode the JWT and extract claims 25 if (idpInitiatedLoginToken != null) { 26 IdpInitiatedLoginClaims claims = scalekitClient.authentication() 27 .getIdpInitiatedLoginClaims(idpInitiatedLoginToken); 28 29 if (claims == null) { 30 response.sendError(HttpStatus.BAD_REQUEST.value(), 31 "Invalid idp_initiated_login token"); 32 return null; 33 } 34 35 // Create authorization options with ONE of the following 36 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 37 if (claims.getConnectionID() != null) { 38 options.setConnectionId(claims.getConnectionID()); 39 } 40 if (claims.getOrganizationID() != null) { 41 options.setOrganizationId(claims.getOrganizationID()); 42 } 43 if (claims.getLoginHint() != null) { 44 options.setLoginHint(claims.getLoginHint()); 45 } 46 if (claims.getRelayState() != null) { 47 options.setState(claims.getRelayState()); 48 } 49 50 // Generate Authorization URL for SP-initiated flow 51 String url = scalekitClient.authentication() 52 .getAuthorizationUrl(redirectUrl, options) 53 .toString(); 54 55 response.sendRedirect(url); 56 return null; 57 } 58 59 // Handle regular login flow here 60 return new RedirectView("/login"); 61 } 62 } ``` ## Implementation details [Section titled “Implementation details”](#implementation-details) ### Endpoint setup [Section titled “Endpoint setup”](#endpoint-setup) Implement this as a backend route, not a frontend page. Scalekit redirects the browser to the Initiate Login URL with a `GET` request; your server reads the `idp_initiated_login` parameter, validates it, and issues its own redirect to continue the flow — the route never renders a page. Your initiate login endpoint will receive requests with the following format: ```sh https://yourapp.com/login?idp_initiated_login= ``` ### JWT token structure [Section titled “JWT token structure”](#jwt-token-structure) The `idp_initiated_login` parameter contains a signed JWT with organization, connection, and user details. ### Error callback format [Section titled “Error callback format”](#error-callback-format) If errors occur, the redirect URI will receive a callback with this format: ```sh https://{your-subdomain}.scalekit.dev/callback ?error="" &error_description="
" ``` After completing the SP-initiated flow, users are redirected back to your callback URL where you can complete the authentication process. Next, let’s look at how to test your IdP-initiated SSO implementation. ## Integrating with a downstream auth provider [Section titled “Integrating with a downstream auth provider”](#integrating-with-a-downstream-auth-provider) If your application uses a third-party service like [Firebase Authentication](/guides/integrations/auth-systems/firebase/) to manage user sessions, you must initiate its sign-in flow after completing **Step 3**. This process has two stages: first, the IdP redirects the user to your app via Scalekit, and second, your app triggers a new sign-in flow with Firebase using the Authorization URL you just generated. The example below shows how to pass the Authorization URL to the Firebase Web SDK. * Firebase (Web SDK) Firebase Web SDK ```javascript 1 import { getAuth, OAuthProvider, signInWithRedirect } from "firebase/auth"; 2 3 // Security: Configure OIDC provider properly to prevent token injection 4 const auth = getAuth(); 5 6 // "scalekit" is the OIDC provider you configured in Firebase 7 const scalekitProvider = new OAuthProvider("scalekit"); 8 9 // Use the authorizationUrl generated in Step 3 10 scalekitProvider.setCustomParameters({ 11 connection_id: "", // Enables Firebase to forward the connection ID to Scalekit 12 }); 13 14 // Initiate Firebase sign-in with Scalekit provider 15 signInWithRedirect(auth, scalekitProvider); ``` ## Security considerations [Section titled “Security considerations”](#security-considerations) While IdP-initiated SSO offers convenience, it comes with significant security risks. Scalekit’s approach converts the flow to SP-initiated to mitigate these vulnerabilities. ### Traditional IdP-initiated SSO security risks [Section titled “Traditional IdP-initiated SSO security risks”](#traditional-idp-initiated-sso-security-risks) **Stolen SAML assertions**: Attackers can steal SAML assertions and use them to gain unauthorized access. If an attacker manages to steal these assertions, they can: * Inject them into another service provider, gaining access to that user’s account * Inject them back into your application with altered assertions, potentially elevating their privileges With a stolen SAML assertion, an attacker can gain access to your application as the compromised user, bypassing the usual authentication process. ### How attackers steal SAML assertions [Section titled “How attackers steal SAML assertions”](#how-attackers-steal-saml-assertions) Attackers can steal SAML assertions through various methods: * **Man-in-the-middle (MITM) attacks**: Intercepting and replacing the SAML response during transmission * **Open redirect attacks**: Exploiting improper endpoint validation to redirect the SAML response to a malicious server * **Leaky logs and headers**: Sensitive information, including SAML assertions, can be leaked through logs or headers * **Browser-based attacks**: Exploiting browser vulnerabilities to steal SAML assertions ### The challenge for service providers [Section titled “The challenge for service providers”](#the-challenge-for-service-providers) The chief problem with stolen assertions is that everything appears legitimate to the service provider (your application). The message and assertion are valid, issued by the expected identity provider, and signed with the expected key. However, the service provider cannot verify whether the assertions are stolen or not. If you encounter issues implementing IdP-initiated SSO: 1. **Verify configuration**: Ensure your redirect URI is properly configured in **Dashboard > Developers > Redirect URLs** 2. **Check JWT processing**: Verify you’re correctly processing the JWT token from the `idp_initiated_login` parameter 3. **Validate error handling**: Ensure your error handling properly captures and processes any error messages 4. **Test connections**: Confirm the organization and connection IDs in the JWT are valid and active 5. **Review logs**: Check both your application logs and Scalekit dashboard logs for debugging information Common issues The most frequent issue is mismatched redirect URLs between your code and the Scalekit dashboard configuration. Ensure URLs match exactly, including protocol (http/https) and trailing slashes. --- # DOCUMENT BOUNDARY --- # Production readiness checklist > A focused checklist for launching your Scalekit SSO integration, based on the core enterprise authentication launch checks. As you prepare to launch enterprise SSO to production, you should confirm that your configuration satisfies the core enterprise checks from the authentication launch checklist. This page extracts the SSO-specific items from the main authentication [production readiness checklist](/authenticate/launch-checklist/) and organizes them for your SSO rollout. Use this checklist alongside the main launch checklist to validate that your SSO flows, admin experience, and network access are ready for enterprise customers. **Verify production environment configuration** Confirm that your environment URL (`SCALEKIT_ENVIRONMENT_URL`), client ID (`SCALEKIT_CLIENT_ID`), and client secret (`SCALEKIT_CLIENT_SECRET`) are correctly configured for your production environment and match your production Scalekit dashboard settings. **Verify SSO integrations with identity providers** Test SSO integrations with your target identity providers (for example, Okta, Azure AD, Google Workspace) using your production environment URL and credentials. **Configure SSO attribute mapping and identifiers** Configure SSO user attribute mapping (email, name, groups) and ensure you use consistent user identifiers (for example, email or `userPrincipalName`) across all SSO connections. **Verify redirect URIs and state validation** Confirm that your redirect URIs are correctly configured in both Scalekit and your identity providers, and that you validate the `state` parameter in callbacks to prevent CSRF attacks. **Test SP-initiated and IdP-initiated SSO flows** Test both SP-initiated and IdP-initiated SSO flows end-to-end in a staging environment before enabling them for production tenants. See [test SSO flows](/sso/guides/test-sso) for detailed scenarios. **Finalize admin portal setup and branding** Configure the self-service admin portal, apply your branding (logo, accent colors), and verify that enterprise admins can manage SSO connections and users as expected. **Review admin portal URL and DNS** Customize the admin portal URL to match your domain (for example, `https://sso.b2b-app.com`), update your `.env` configuration after CNAME setup, and confirm that your customers can access the portal from their networks. **Verify customer network and firewall access** Ask your enterprise customers to whitelist your Scalekit environment domain and related endpoints so SSO redirects and admin portal access work behind their VPNs and firewalls. **Harden error handling and monitoring for SSO** Test SSO error scenarios (for example, misconfigured connections, invalid assertions, and deactivated users), and set up logging and alerts so you can quickly detect and remediate SSO issues. --- # DOCUMENT BOUNDARY --- # Onboard enterprise customers > Complete workflow for enabling enterprise SSO and self-serve configuration for your customers Enterprise SSO enables users to authenticate to your application using their organization’s identity provider (IdP) such as Okta, Microsoft Entra ID, or Google Workspace. This provides enterprise customers with a secure, centralized authentication experience while reducing password management overhead. ![How Scalekit connects your application to enterprise identity providers](/.netlify/images?url=_astro%2Fhow-scalekit-connects.CrZX8E30.png\&w=5776\&h=1924\&dpl=6aaa70ad2ea7b40008ad2afd) This guide walks you through the complete workflow for onboarding enterprise customers with SSO. You’ll learn how to create organizations, provide admin portal access, enable domain-based SSO, and verify the integration. Before onboarding enterprise customers, ensure you have completed the [Full Stack Auth quickstart](/authenticate/fsa/quickstart/) to set up basic authentication in your application. ## Table of contents * [Create organization](#create-organization) * [Provide admin portal access](#provide-admin-portal-access) * [Customer configures SSO](#customer-configures-sso) * [Verify domain ownership](#verify-domain-ownership) 1. ## Create organization Create an organization in Scalekit to represent your enterprise customer: * Log in to the [Scalekit dashboard](https://app.scalekit.com) * Navigate to **Dashboard > Organizations** * Click **Create Organization** * Enter the organization name and relevant details * Save the organization Each organization in Scalekit represents one of your enterprise customers and can have its own SSO configuration, directory sync settings, and domain associations. 2. ## Provide admin portal access Give your customer’s IT administrator access to the self-serve admin portal to configure their identity provider. Scalekit provides two integration methods: **Option 1: Share a no-code link** Quick setup Generate and share a link to the admin portal: * Select the organization from **Dashboard > Organizations** * Click **Generate link** in the organization overview * Share the link with your customer’s IT admin via email, Slack, or your preferred channel The link remains valid for 7 days and can be revoked anytime from the dashboard. **Link properties:** | Property | Details | | -------------- | ------------------------------------------------------------------------------- | | **Expiration** | Links expire after 7 days | | **Revocation** | Revoke links anytime from the dashboard | | **Sharing** | Share via email, Slack, or any preferred channel | | **Security** | Anyone with the link can view and update the organization’s connection settings | The generated link follows this format: Portal link example ```http https://your-app.scalekit.dev/magicLink/2cbe56de-eec4-41d2-abed-90a5b82286c4_p ``` Security consideration Treat portal links as sensitive credentials. Anyone with the link can view and modify the organization’s SSO and SCIM configuration. **Option 2: Embed the portal** Seamless experience Embed the admin portal directly in your application so customers can configure SSO without leaving your interface. The portal link must be generated programmatically on each page load for security. Each generated link is single-use and expires after 1 minute, though once loaded, the session remains active for up to 6 hours. * Node.js ```bash npm install @scalekit-sdk/node ``` * Python ```sh pip install scalekit-sdk-python ``` * Go ```sh go get -u github.com/scalekit-inc/scalekit-sdk-go ``` * Java ```groovy /* Gradle users - add the following to your dependencies in build file */ implementation "com.scalekit:scalekit-sdk-java:2.1.3" ``` ```xml com.scalekit scalekit-sdk-java 2.1.3 ``` ### Generate portal link Use the Scalekit SDK to generate a unique, embeddable admin portal link for an organization. Call this API endpoint each time you render the page containing the iframe: * Node.js Express.js ```javascript 1 import { Scalekit } from '@scalekit-sdk/node'; 2 3 const scalekit = new Scalekit( 4 process.env.SCALEKIT_ENVIRONMENT_URL, 5 process.env.SCALEKIT_CLIENT_ID, 6 process.env.SCALEKIT_CLIENT_SECRET, 7 ); 8 9 async function generatePortalLink(organizationId) { 10 const link = await scalekit.organization.generatePortalLink(organizationId); 11 return link.location; // Use as iframe src 12 } ``` * Python Flask ```python 1 from scalekit import Scalekit 2 import os 3 4 scalekit_client = Scalekit( 5 environment_url=os.environ.get("SCALEKIT_ENVIRONMENT_URL"), 6 client_id=os.environ.get("SCALEKIT_CLIENT_ID"), 7 client_secret=os.environ.get("SCALEKIT_CLIENT_SECRET") 8 ) 9 10 def generate_portal_link(organization_id): 11 link = scalekit_client.organization.generate_portal_link(organization_id) 12 return link.location # Use as iframe src ``` * Go Gin ```go 1 import ( 2 "context" 3 "os" 4 5 "github.com/scalekit/sdk-go" 6 ) 7 8 scalekitClient := scalekit.New( 9 os.Getenv("SCALEKIT_ENVIRONMENT_URL"), 10 os.Getenv("SCALEKIT_CLIENT_ID"), 11 os.Getenv("SCALEKIT_CLIENT_SECRET"), 12 ) 13 14 func generatePortalLink(organizationID string) (string, error) { 15 ctx := context.Background() 16 link, err := scalekitClient.Organization().GeneratePortalLink(ctx, organizationID) 17 if err != nil { 18 return "", err 19 } 20 return link.Location, nil // Use as iframe src 21 } ``` * Java Spring Boot ```java 1 import com.scalekit.client.Scalekit; 2 import com.scalekit.client.models.Link; 3 import com.scalekit.client.models.Feature; 4 import java.util.Arrays; 5 6 Scalekit scalekitClient = new Scalekit( 7 System.getenv("SCALEKIT_ENVIRONMENT_URL"), 8 System.getenv("SCALEKIT_CLIENT_ID"), 9 System.getenv("SCALEKIT_CLIENT_SECRET") 10 ); 11 12 public String generatePortalLink(String organizationId) { 13 Link portalLink = scalekitClient.organizations() 14 .generatePortalLink(organizationId, Arrays.asList(Feature.sso, Feature.dir_sync)); 15 return portalLink.getLocation(); // Use as iframe src 16 } ``` The API returns a JSON object with the portal link. Use the `location` property as the iframe `src`: API response ```json { "id": "8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "location": "https://random-subdomain.scalekit.dev/magicLink/8930509d-68cf-4e2c-8c6d-94d2b5e2db43", "expireTime": "2024-10-03T13:35:50.563013Z" } ``` Embed portal in iframe ```html ``` Embed the portal in your application’s settings or admin section where customers manage authentication configuration. Listen for UI events from the embedded portal to respond to configuration changes, such as when SSO is enabled or the session expires. See the [Admin portal UI events reference](/reference/admin-portal/ui-events/) for details on handling these events. ### Configuration and session | Setting | Requirement | | --------------------- | ----------------------------------------------------------------------------- | | **Redirect URI** | Add your application domain at **Dashboard > Developers > API Configuration** | | **iframe attributes** | Include `allow="clipboard-write"` for copy-paste functionality | | **Dimensions** | Minimum recommended height: 600px | | **Link expiration** | Generated links expire after 1 minute if not loaded | | **Session duration** | Portal session remains active for up to 6 hours once loaded | | **Single-use** | Each generated link can only be used once to initialize a session | 3. ## Customer configures SSO After receiving admin portal access, your customer’s IT administrator: * Opens the admin portal (via shared link or embedded iframe) * Selects their identity provider (Okta, Microsoft Entra ID, Google Workspace, etc.) * Follows the provider-specific setup guide * Enters the required configuration (metadata URL, certificates, etc.) * Tests the connection * Activates the SSO connection Once configured, the SSO connection appears as active in your organization’s settings: ![Active enterprise SSO connection](/.netlify/images?url=_astro%2Fenterpise-sso-1.BfV9F7Wk.png\&w=2074\&h=1116\&dpl=6aaa70ad2ea7b40008ad2afd) 4. ## Verify domain ownership After SSO is configured, verify the organization’s email domains to enable automatic SSO routing. When domains are verified, users with matching email addresses are automatically redirected to their organization’s SSO login. This is also called as **Home Realm Discovery**. ### Manual verification (no DNS required) Domains added via the Scalekit Dashboard or API are marked as **Admin-verified** — no DNS challenge is required. Use this when you have already confirmed domain ownership through another process (contract, business verification, etc.) and want to activate SSO routing immediately. **Via Scalekit Dashboard:** * Navigate to **Dashboard > Organizations** and select the organization * Go to **Overview > Organization Domains** * Click **Add domain** and enter the domain name (e.g., `megacorp.com`) ![Organization domain verification in dashboard](/.netlify/images?url=_astro%2Forg_domain.CnZ3T4x-.png\&w=2940\&h=1588\&dpl=6aaa70ad2ea7b40008ad2afd) **Via API:** * cURL ```sh curl 'https:///api/v1/organizations//domains' \ --request POST \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "domain": "megacorp.com", "domain_type": "ORGANIZATION_DOMAIN" }' ``` * Node.js ```ts 1 const domain = await scalekit.organization.createDomain(organizationId, { 2 domain: 'megacorp.com', 3 domainType: 'ORGANIZATION_DOMAIN', 4 }); ``` * Python ```python 1 domain = scalekit_client.organization.create_domain( 2 organization_id, 3 domain="megacorp.com", 4 domain_type="ORGANIZATION_DOMAIN", 5 ) ``` * Go ```go 1 domain, err := scalekitClient.Organization().CreateDomain( 2 ctx, 3 organizationID, 4 scalekit.CreateDomainOptions{ 5 Domain: "megacorp.com", 6 DomainType: "ORGANIZATION_DOMAIN", 7 }, 8 ) ``` * Java ```java 1 Domain domain = scalekitClient.organizations() 2 .createDomain(organizationId, new CreateDomainOptions() 3 .setDomain("megacorp.com") 4 .setDomainType("ORGANIZATION_DOMAIN")); ``` ### DNS verification (self-serve for org admins) DNS verification lets your customer’s IT admin prove domain ownership by publishing a TXT record — without involving your team. Scalekit displays the TXT record to publish, then polls DNS automatically until verified. 1. Enable the `Domain Verification` feature for the organization (Dashboard org **Overview** → toggle **Domain Verification**, or via the [API](/apis/#tag/organizations/PATCH/api/v1/organizations/%7Bid%7D/settings)). 2. Generate an Admin Portal link and share it with the org admin. 3. The admin enters the domain in the portal, copies the displayed TXT record, and adds it to their DNS provider (e.g., Cloudflare, Route 53, GoDaddy). 4. Scalekit detects the TXT record automatically and marks the domain as **Verified**. ![Domain verification via admin portal](/.netlify/images?url=_astro%2F2026-05-26-19-01-37.C8CAmZIi.png\&w=2196\&h=1596\&dpl=6aaa70ad2ea7b40008ad2afd) Once verified, users with email addresses from that domain (e.g., `user@megacorp.com`) can authenticate using their organization’s SSO. ## Customize the admin portal Match the admin portal to your brand identity. Configure branding at **Dashboard > Settings > Branding**: | Option | Description | | ---------------- | --------------------------------------------------------- | | **Logo** | Upload your company logo (displayed in the portal header) | | **Accent color** | Set the primary color to match your brand palette | | **Favicon** | Provide a custom favicon for browser tabs | For additional customization options including custom domains, see the [Custom domain guide](/guides/custom-domain/). ## 5. Test the integration [Section titled “5. Test the integration”](#5-test-the-integration) Before rolling out SSO to your customers, thoroughly test the integration: * **Use the IdP Simulator** during development to test without configuring real identity providers * **Test with real providers** like Okta or Microsoft Entra ID in your staging environment * **Validate all scenarios**: SP-initiated SSO, IdP-initiated SSO, and error handling For complete testing instructions, see the [Test SSO integration guide](/sso/guides/test-sso/). --- # DOCUMENT BOUNDARY --- # Introduction to Single Sign-on > Learn to basics of Single Sign-On (SSO), including how SAML and OIDC protocols work, and how Scalekit simplifies enterprise authentication. Single Sign-On (SSO) streamlines user access by enabling a single authentication event to grant access to multiple applications with the same credentials. For example, logging into one Google service, such as Gmail, automatically authenticates you to YouTube, Google Drive, and other Google platforms. There are two key benefits to the users and organizations with a secure single sign-on implementation: 1. User can seamlessly access multiple applications using only one set of credentials. 2. User credentials are managed in a centralized identity system. This enables Admins to easily configure and manage authentication policies for all their users from the centralized identity provider. Furthermore, this integrated SSO mechanism enhances user convenience, boosts productivity, and reduces the risks associated with password fatigue and reuse. These security & administration benefits are driving factors for enterprise organizations to only procure SaaS applications that offer SSO-based authentication. ## Understand how Single Sign-On works [Section titled “Understand how Single Sign-On works”](#understand-how-single-sign-on-works) Fundamentally, Single Sign-on works by exchanging user information in a pre-determined format between two trusted parties - your application and your customer’s identity provider (aka IdP). Most of these interactions happen in the browser context as some steps need user intervention. To ensure secure exchange of user information between your application and your customer’s identity provider, most IdPs support two protocols: Secure Assertion Markup Language (SAML) or OpenID Connect (OIDC). The objective of both these protocols is same: allow secure user information exchange between the Service Provider (your application) and Identity Provider (your customer’s identity system). These protocols differ in how these systems trust each other, communicate, and exchange user information. Let’s understand these protocols at a high level. ## Understanding SAML protocol [Section titled “Understanding SAML protocol”](#understanding-saml-protocol) SAML 2.0 (Secure Assertion Markup Language) has been in use since 2005 and is also most widely implemented protocol. SAML exchanges user information using XML files via HTTPS or SOAP. But, before the user information is exchanged between the two parties, they need to establish the trust between them. Trust is established by exchanging information about each other as part of SAML configuration parameters like Assertion Consumer Service URL (ACS URL), Entity ID, X.509 Certificates, etc. After the trust has been established, subsequent user information can be exchanged in two ways - 1. Your application requesting for a user’s information - this is Service Provider initiated login flow 2. Or the identity provider directly shares user details via a pre-configured ACS URL - this is Identity Provider initiated login flow Let’s understand these two SSO flows. ### Implement Service Provider initiated flow [Section titled “Implement Service Provider initiated flow”](#implement-service-provider-initiated-flow) ![SP initiated SSO workflow](/.netlify/images?url=_astro%2F1.DdT6sA5U.png\&w=3536\&h=2644\&dpl=6aaa70ad2ea7b40008ad2afd) For service provider initiated SSO flow, 1. User tries to access your application and your app identifies that the user’s credentials need to be verified by their identity provider. 2. Your application requests the identity provider for the user’s information. 3. The identity provider authenticates the user and returns user details as “assertions” to your application. 4. You validate assertions, retrieve the user information, and if everything checks, allow the user to successfully login to your application. As you can imagine, in this workflow, the user login behaviour starts from your application and that’s why this is termed as service provider initiated SSO (aka SP-initiated SSO) ### Implement Identity Provider initiated flow [Section titled “Implement Identity Provider initiated flow”](#implement-identity-provider-initiated-flow) ![IdP initiated SSO workflow](/.netlify/images?url=_astro%2F2-idp-init-sso.CAu--K_L.png\&w=3536\&h=2168\&dpl=6aaa70ad2ea7b40008ad2afd) In case of Identity Provider initiated SSO, 1. User logs into their identity provider portal and selects your application from within the IdP portal. 2. Identity Provider sends the user details as assertions to your application. 3. You validate assertions, retrieve the user information, and if everything checks, allow the user to successfully login to your application. Since the user login workflow starts from the Identity Provider portal (and not from your application), this flow is called Identity Provider initiated SSO (aka IdP-initiated SSO). #### Mitigate security risks [Section titled “Mitigate security risks”](#mitigate-security-risks) IdP initiated SSO is susceptible to common security attacks like Man In the Middle attack, Stolen Assertion attack or Assertion Replay attack etc. Read the [IdP initiated SSO](/sso/guides/idp-init-sso) guide to understand these risks and how to mitigate them. ## Understanding OIDC protocol [Section titled “Understanding OIDC protocol”](#understanding-oidc-protocol) OpenID Connect (OIDC) is an authentication protocol based on top of OAuth 2.0 to simplify the user information exchange process between Relying Party (your application) and the OpenID Provider (your customer’s Identity Provider). The OIDC protocol exchanges user information via signed JSON Web Tokens (JWT) over HTTPS. Because of the simplified nature of handling JWTs, it is often used in modern web applications, native desktop clients and mobile applications. With the latest extensions to the OIDC protocol like Proof Key of Code Exchange (PKCE) and Demonstrating Proof of Possession (DPoP), the overall security of user exchange information is strengthened. In its current format, OIDC only supports SP initiated Login. In this flow: 1. User tries to access your application. You identify that this user’s credentials need to be verified by their Identity Provider. 2. Your application requests the user’s Identity Provider for the user’s information via an OAuth2 request. 3. Identity Provider authenticates the user and sends the user’s details with an authorization\_code to a pre-registered redirect\_url on your server. 4. You will exchange the code for the actual user details by providing your information with the Identity provider. 5. Identity Provider will then send the user information in the form of JWTs. You retrieve the user information from those assertions and if everything is valid, you will allow the user inside your application. #### Simplify SSO with Scalekit [Section titled “Simplify SSO with Scalekit”](#simplify-sso-with-scalekit) Scalekit serves as an intermediary, abstracting the complexities involved in handling SSO with SAML and OIDC protocols. By integrating with Scalekit in just a few lines of code, your application can connect with numerous IdPs efficiently, ensuring security and compliance. --- # DOCUMENT BOUNDARY --- # Map user attributes to IdP > Learn how to add and map custom user attributes, such as an employee number, from an Identity Provider (IdP) like Okta using Scalekit. Scalekit simplifies Single Sign-On (SSO) by managing user information between Identity Providers (IdPs) and B2B applications. The IdPs provide standard user properties, such as `email` and `firstname`, to your application, thus helping recognize the user. Consider a scenario where you want to get the employee number of the user logging into the application. This guide demonstrates how to add your own custom attribute (such as `employee_number`) and map its value from the Identity Provider. Broadly, we’ll go through two steps: 1. Create a new attribute in Scalekit 2. Set up the value that the Identity Provider should relay to this attribute ## Create a new attribute [Section titled “Create a new attribute”](#create-a-new-attribute) Let’s begin by signing into the Scalekit dashboard: 1. Navigate to **Dashboard > SSO > User Attributes** 2. Click **Add Attribute** 3. Add “Employee Number” as Display name ![add attribute](/.netlify/images?url=_astro%2F1-add-attribute-scalekit.ChxO8Ovm.png\&w=1146\&h=600\&dpl=6aaa70ad2ea7b40008ad2afd) You’ll now notice “Employee Number” in the list of user attributes. Scalekit is now ready to receive this attribute from your customers’ Identity Providers (IdPs). ![see attribute](/.netlify/images?url=_astro%2F2.42Rj4Bw-.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) ## Set up IdP attributes Okta example [Section titled “Set up IdP attributes ”](#set-up-idp-attributes-) Now, we’ll set up an Identity Provider to send these details. For the purposes of this guide, we’ll use Okta as IdP to send the `employee_number` to Scalekit. However, similar functionality can be achieved using any other IdP. Note that in this specific Okta instance, the “Employee Number” is a default attribute that hasn’t been utilized yet. Before you proceed forward, it’s important to modify the profile’s `employee_number` attribute with any desired number for this example (for example, `1729`). For a detailed guide on how to achieve this, consult [Okta’s dedicated help article on updating profile attributes](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-edit-user-attributes.htm#:~:text=Click%20the%20Profile%20tab). Alternatively, you can [add a new custom attribute in the Okta Profile Editor](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-add-custom-user-attributes.htm#:~:text=In%20the%20Admin%20Console%20%2C%20go%20to%20Directory%20Profile%20Editor). ![map attribute](/.netlify/images?url=_astro%2F3-map-attribute-okta.CtVAf_eI.png\&w=2764\&h=1578\&dpl=6aaa70ad2ea7b40008ad2afd) ## Test SSO for new attributes [Section titled “Test SSO for new attributes”](#test-sso-for-new-attributes) In the Scalekit dashboard, navigate to **Dashboard > Organizations**. 1. Select the organization that you’d like to add custom attribute to 2. Navigate to the SSO Connection 3. Click **Test Connection** - you’ll find this if the IdP has already been established ![map attr scalekit](/.netlify/images?url=_astro%2F4-map-attribute-scalekit.BYU0mngo.png\&w=1978\&h=1520\&dpl=6aaa70ad2ea7b40008ad2afd) Upon testing the connection, if you notice the updated user profile (`employee_number` as `1729` in this example), this signifies a successful test. Subsequently, these details will be integrated into your B2B application through Scalekit. This ensures seamless recognition and handling of customer user attributes during the SSO authentication process. ## Reserved attribute names [Section titled “Reserved attribute names”](#reserved-attribute-names) Some attribute names are **reserved by Scalekit** and must not be used for custom attributes. Using a reserved name causes silent failures — the custom attribute value is silently dropped or overwritten during SSO. | Name | Purpose | | ----------------------------------- | --------------------------------------------------------- | | `roles` | Used by Scalekit for FSA role-based access control (RBAC) | | `permissions` | Used by Scalekit for FSA permissions | | `email` | Standard claim — always populated from IdP | | `email_verified` | Standard claim | | `name`, `given_name`, `family_name` | Standard profile claims | | `sub`, `oid`, `sid` | Internal Scalekit identifiers | If your IdP sends an attribute named `roles`, it **will not** appear as a custom attribute in the JWT. Instead, rename it to something unique (e.g., `user_role` or `idp_roles`) in both Scalekit and your IdP attribute mapping. ## Access custom attributes from the ID token [Section titled “Access custom attributes from the ID token”](#access-custom-attributes-from-the-id-token) After configuring a custom attribute in Scalekit, its value appears in the ID token as a JWT claim. Use the Scalekit SDK to validate the token and read the claim: * Node.js Read custom attributes from ID token ```typescript 1 import type { IdTokenClaim } from '@scalekit-sdk/node'; 2 3 // Validate the ID token and cast to include your custom attributes 4 const claims = await scalekit.validateToken>(idToken); 5 const employeeNumber = claims['employee_number']; 6 const userRole = claims['user_role']; // use 'user_role', not 'roles' ``` * Python Read custom attributes from ID token ```python 1 # Validate the ID token — returns a dict of all claims 2 claims = scalekit_client.validate_token(id_token) 3 employee_number = claims.get('employee_number') 4 user_role = claims.get('user_role') # use 'user_role', not 'roles' ``` * Go Read custom attributes from ID token ```go 1 // Validate the ID token — returns a map of all claims 2 claims, err := scalekitClient.ValidateToken(ctx, idToken) 3 if err != nil { 4 log.Fatal(err) 5 } 6 employeeNumber := claims["employee_number"] 7 userRole := claims["user_role"] // use "user_role", not "roles" ``` * Java Read custom attributes from ID token ```java 1 import java.util.Map; 2 3 // Validate the ID token — returns a map of all claims 4 Map claims = scalekitClient.authentication().validateToken(idToken); 5 Object employeeNumber = claims.get("employee_number"); 6 Object userRole = claims.get("user_role"); // use "user_role", not "roles" ``` --- # DOCUMENT BOUNDARY --- # SSO simulator > Test Enterprise SSO based authentication using our SSO Simulator without configuring SAML or OIDC based SSO with a real IdP After implementing Single Sign-On using our [Quickstart guide](/authenticate/sso/add-modular-sso/), you need to validate your integration for all possible scenarios. This guide shows you how to test your SSO implementation using two approaches: 1. **SSO Simulator (quick testing):** Test all SSO scenarios without external services. Your development environment includes a pre-configured test organization with an SSO connection to our SSO Simulator. 2. **Real identity provider (production-ready testing):** Test with actual identity providers like Okta or Microsoft Entra ID to simulate real customer scenarios. To ensure a successful SSO implementation, test all three scenarios described in this guide before deploying to production: SP-initiated SSO, IdP-initiated SSO, and error handling. ## Testing with SSO Simulator Quick testing [Section titled “Testing with SSO Simulator ”](#testing-with-sso-simulator-) The SSO Simulator allows you to test all SSO scenarios without requiring external services. Your development environment includes a pre-configured test organization with an SSO connection to our SSO Simulator and test domains like `@example.com` or `@example.org`. To locate the test organization, navigate to **Dashboard > Organizations** and select **Test Organization**. ![Test Organization](/.netlify/images?url=_astro%2F2.CCYEcEtj.png\&w=2786\&h=1746\&dpl=6aaa70ad2ea7b40008ad2afd) ### Service provider (SP) initiated SSO Scenario 1 [Section titled “Service provider (SP) initiated SSO ”](#service-provider-sp-initiated-sso-) In this common scenario, users start the Single Sign-On process from your application’s login page. ![SP initiated SSO](/.netlify/images?url=_astro%2F1.Bn8Ae4ZM.png\&w=4936\&h=3744\&dpl=6aaa70ad2ea7b40008ad2afd) #### Generate authorization URL [Section titled “Generate authorization URL”](#generate-authorization-url) Generate an authorization URL with your test organization ID. This redirects users to Scalekit’s hosted login page, which will then redirect to the SSO Simulator. * Node.js Express.js ```javascript 1 // Use your test organization ID from the dashboard 2 const options = { 3 organizationId: 'org_32656XXXXXX0438' // Replace with your test organization ID 4 }; 5 6 // Generate Authorization URL that redirects to SSO Simulator 7 const authorizationURL = scalekit.getAuthorizationUrl(redirectUrl, options); 8 9 // Redirect user to start SSO flow 10 res.redirect(authorizationURL); ``` * Python Flask ```python 1 # Use your test organization ID from the dashboard 2 options = { 3 "organizationId": 'org_32656XXXXXX0438' # Replace with your test organization ID 4 } 5 6 # Generate Authorization URL that redirects to SSO Simulator 7 authorization_url = scalekit_client.get_authorization_url( 8 redirect_url, 9 options, 10 ) 11 12 # Redirect user to start SSO flow 13 return redirect(authorization_url) ``` * Go Gin ```go 1 // Use your test organization ID from the dashboard 2 options := scalekit.AuthorizationUrlOptions{ 3 OrganizationId: "org_32656XXXXXX0438", // Replace with your test organization ID 4 } 5 6 // Generate Authorization URL that redirects to SSO Simulator 7 authorizationURL := scalekitClient.GetAuthorizationUrl( 8 redirectUrl, 9 options, 10 ) 11 12 // Redirect user to start SSO flow 13 c.Redirect(http.StatusFound, authorizationURL) ``` * Java Spring Boot ```java 1 // Use your test organization ID from the dashboard 2 AuthorizationUrlOptions options = new AuthorizationUrlOptions(); 3 options.setOrganizationId("org_32656XXXXXX0438"); // Replace with your test organization ID 4 5 // Generate Authorization URL that redirects to SSO Simulator 6 String authorizationURL = scalekitClient 7 .authentication() 8 .getAuthorizationUrl(redirectUrl, options) 9 .toString(); 10 11 // Redirect user to start SSO flow 12 return "redirect:" + authorizationURL; ``` #### Test the SSO flow [Section titled “Test the SSO flow”](#test-the-sso-flow) After generating the authorization URL, users are redirected to the SSO Simulator: 1. Select **User login via SSO** from the dropdown menu 2. Enter test user details (email, name, etc.) to simulate authentication 3. Click **Submit** to complete the simulation ![SSO Simulator form](/.netlify/images?url=_astro%2F2.1.BEM1Vo-J.png\&w=2646\&h=1652\&dpl=6aaa70ad2ea7b40008ad2afd) After submitting the form, your application receives an `idToken` containing the user details you entered: ![ID token response](/.netlify/images?url=_astro%2F2.2.tePTMu6U.png\&w=2182\&h=1146\&dpl=6aaa70ad2ea7b40008ad2afd) ### Identity provider (IdP) initiated SSO Scenario 2 [Section titled “Identity provider (IdP) initiated SSO ”](#identity-provider-idp-initiated-sso-) In this scenario, users start the sign-in process from their identity provider (typically through an applications catalog) rather than from your application’s login page. Your application must handle this flow by detecting IdP-initiated requests and converting them to SP-initiated SSO. If you haven’t implemented IdP-initiated SSO yet, follow our [IdP-initiated SSO implementation guide](/sso/guides/idp-init-sso) before testing this scenario. ![How IdP-initiated SSO works](/.netlify/images?url=_astro%2F4.DI1M7pT-.png\&w=4936\&h=4432\&dpl=6aaa70ad2ea7b40008ad2afd) #### Test IdP-initiated SSO flow [Section titled “Test IdP-initiated SSO flow”](#test-idp-initiated-sso-flow) 1. Generate the authorization URL using your test organization 2. When redirected to the SSO Simulator, select **IdP initiated SSO** from the dropdown menu 3. Enter test user details to simulate the login 4. Click **Submit** to complete the simulation ![IdP initiated SSO form](/.netlify/images?url=_astro%2F3.1.CmRUnvaS.png\&w=2530\&h=1656\&dpl=6aaa70ad2ea7b40008ad2afd) #### Verify callback handling [Section titled “Verify callback handling”](#verify-callback-handling) Your callback handler receives the IdP-initiated request and must process it correctly: ![IdP initiated callback](/.netlify/images?url=_astro%2F3.2.D4V_v_y-.png\&w=2024\&h=486\&dpl=6aaa70ad2ea7b40008ad2afd) Your application should: 1. Detect the IdP-initiated request based on the request parameters 2. Retrieve connection details (`connection_id` or `organization_id`) from Scalekit 3. Generate a new authorization URL to convert the IdP-initiated flow to SP-initiated SSO 4. Complete the authentication flow ### Error handling Scenario 3 [Section titled “Error handling ”](#error-handling-) Your application should gracefully handle error scenarios to provide a good user experience. SSO failures can occur due to misconfiguration, incomplete user profiles, or integration issues. #### Test error scenarios [Section titled “Test error scenarios”](#test-error-scenarios) 1. Generate and redirect to the authorization URL 2. In the SSO Simulator, select **Error** from the dropdown menu 3. Verify your callback handler processes the error correctly 4. Ensure users see an appropriate error message ![Error scenario in SSO Simulator](/.netlify/images?url=_astro%2F5.DIgPtBxP.png\&w=2364\&h=1216\&dpl=6aaa70ad2ea7b40008ad2afd) ## Testing with real identity providers Production-ready [Section titled “Testing with real identity providers ”](#testing-with-real-identity-providers-) After validating your SSO implementation with the SSO Simulator, test with real identity providers like Okta or Microsoft Entra ID to simulate actual customer scenarios. This ensures your integration works correctly with production identity systems. ### Setup your test environment [Section titled “Setup your test environment”](#setup-your-test-environment) To simulate a real customer onboarding scenario, create a new organization with a real SSO connection: 1. Create an organization at **Dashboard > Organizations** with a name that reflects a test customer 2. Generate an **Admin Portal link** from the organization’s overview page 3. Open the Admin Portal link and follow the integration guide to set up an SSO connection: * [Okta SAML integration guide](/guides/integrations/sso-integrations/okta-saml/) * [Microsoft Entra ID integration guide](/guides/integrations/sso-integrations/azure-ad-saml/) * [Other SSO integrations](/guides/integrations/) ### Service provider (SP) initiated SSO Scenario 1 [Section titled “Service provider (SP) initiated SSO ”](#service-provider-sp-initiated-sso--1) Test the most common SSO scenario where users start the authentication flow from your application’s login page. ![SP initiated SSO workflow](/.netlify/images?url=_astro%2F1.Bn8Ae4ZM.png\&w=4936\&h=3744\&dpl=6aaa70ad2ea7b40008ad2afd) #### Validate the flow [Section titled “Validate the flow”](#validate-the-flow) 1. **Generate authorization URL**: Create an authorization URL with your test organization’s ID (see [Authorization URL documentation](/sso/guides/authorization-url/)) 2. **User authentication**: Verify that Scalekit redirects users to the correct identity provider 3. **Callback handling**: Confirm your application receives the authorization code at your redirect URI 4. **Token exchange**: Verify you can exchange the authorization code for user details and tokens 5. **Session creation**: Ensure your application creates a session and logs the user in successfully Your application should successfully retrieve user details including email, name, and any custom attributes configured in the SSO connection. ### Identity provider (IdP) initiated SSO Scenario 2 [Section titled “Identity provider (IdP) initiated SSO ”](#identity-provider-idp-initiated-sso--1) Test the scenario where users start authentication from their identity provider’s application catalog. ![IdP-initiated SSO workflow](/.netlify/images?url=_astro%2Fidp-initiated-sso.v3FnpBpw.png\&w=3536\&h=2168\&dpl=6aaa70ad2ea7b40008ad2afd) #### Validate the flow [Section titled “Validate the flow”](#validate-the-flow-1) 1. **Initial callback**: User is redirected to your default redirect URI with IdP-initiated request parameters 2. **Detection logic**: Your application detects this as an IdP-initiated request (based on the request parameters) 3. **SP-initiated conversion**: Your application initiates SP-initiated SSO by generating an authorization URL 4. **IdP redirect**: User is redirected to the identity provider based on the authorization URL 5. **Final callback**: After authentication, user is redirected back with an authorization code and state parameter 6. **Token exchange**: Exchange the code for user details and complete the login For implementation details, see our [IdP-initiated SSO implementation guide](/sso/guides/idp-init-sso/). Default redirect URL configuration Ensure your default redirect URL is correctly configured at **Dashboard > Developers > Redirect URLs**. This URL receives IdP-initiated requests. ### Error handling Scenario 3 [Section titled “Error handling ”](#error-handling--1) Test how your application handles SSO failures. Common error scenarios include: * Misconfigured SSO connections (wrong certificates, invalid metadata) * Incomplete user profiles (missing required attributes) * Expired or revoked SSO connections * Network or integration issues with the identity provider #### Validate error handling [Section titled “Validate error handling”](#validate-error-handling) 1. Review the [SSO integration error codes](/sso/reference/sso-integration-errors/) documentation 2. Test each applicable error scenario by intentionally misconfiguring your SSO connection 3. Verify your application displays appropriate, user-friendly error messages 4. Ensure errors are logged for debugging purposes 5. Confirm users can retry authentication or contact support ## Next steps [Section titled “Next steps”](#next-steps) After thoroughly testing your SSO implementation: 1. Review the [SSO launch checklist](/sso/guides/launch-checklist/) to ensure production readiness 2. Configure the [Admin Portal](/guides/admin-portal/) for your customers to self-serve SSO setup 3. Implement [custom domain](/guides/custom-domain/) for a seamless branded experience 4. Set up [webhooks](/authenticate/implement-workflows/implement-webhooks/) to receive real-time authentication events --- # DOCUMENT BOUNDARY --- # Normalized user profile > Learn how Scalekit's normalized user profiles standardize identity data across providers, streamlining single sign-on (SSO) integration and user management. When a user logs in with SSO, each identity provider shares the user profile information in their own format. This adds complexity for the application developers to parse the user profile info and code related identity workflows. To make this seamless for developers, Scalekit normalizes the user profile info into a standard set of fields across all identity providers. This means that you’d always receive the user profile payload in a fixed set of fields, irrespective of the identity provider and protocol you interact with. This is one of our foundational aspects of the unified SSO solution. Sample normalized user profile ```json 1 { 2 "email": "john.doe@acmecorp.com", 3 "email_verified": true, 4 "family_name": "Doe", 5 "given_name": "John", 6 "locale": "en", 7 "name": "John Doe", 8 "picture": "https://lh3.googleusercontent.com/a/ACg8ocKNE4TZ...iEma17URCEf=s96-c", 9 "sub": "conn_17576372041941092;google-oauth2|104630259163176101050", 10 "identities": [ 11 { 12 "connection_id": "conn_17576372041941092", 13 "organization_id": "org_17002852291444836", 14 "connection_type": "OIDC", 15 "provider_name": "AUTH0", 16 "social": false, 17 "provider_raw_attributes": { 18 "aud": "ztTgHijLLguDXJQab0oiPyIcDLXXrJX6", 19 "email": "john.doe@acmecorp.com", 20 "email_verified": true, 21 "exp": 1714580633, 22 "family_name": "Doe", 23 "given_name": "John", 24 "iat": 1714544633, 25 "iss": "https://dev-rmmfmus2g7vverbf.us.auth0.com/", 26 "locale": "en", 27 "name": "John Doe", 28 "nickname": "john.doe", 29 "nonce": "Lof9SpxEzs9dhUlJzgrrbQ==", 30 "picture": "https://lh3.googleusercontent.com/a/ACg8ocKNE4T...17URCEf=s96-c", 31 "sid": "5yqRJIfjPh8c7lr1s2N-IbY6WR8VyaIZ", 32 "sub": "google-oauth2|104630259163176101050", 33 "updated_at": "2024-04-30T10:02:30.988Z" 34 } 35 } 36 ] 37 } ``` ## Full list of user profile attributes [Section titled “Full list of user profile attributes”](#full-list-of-user-profile-attributes) | Profile attribute | Data type | Description | | ----------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | `sub` | string | An identifier for the user, as submitted by the identity provider that completed the single sign-on. | | `email` | string | The user’s email address. | | `email_verified` | boolean | True if the user’s e-mail address has been verified as claimed by the identity provider; otherwise false. | | `name` | string | Fully formatted user’s name | | `family_name` | string | The user’s surname or last name. | | `given_name` | string | The user’s given name or first name. | | `locale` | string | The user’s locale, represented by a BCP 47 language tag. Example: ‘en’ | | `picture` | string | The user’s profile picture in URL format | | `identities` | Array of [Identity objects](/sso/guides/user-profile-details/#identity-object-attributes) | Array of all identity information received from the identity providers in the raw format | ### Identity object attributes [Section titled “Identity object attributes”](#identity-object-attributes) | Identity attribute | Data type | Description | | ------------------------- | --------- | ----------------------------------------------------------------------------------------------------- | | `organization_id` | string | Unique ID of the organization to which this user belongs to | | `connection_id` | string | Unique ID of the connection for which this identity data is fetched from | | `connection_type` | string | type of the connection: SAML or OIDC | | `provider_name` | string | name of the connection provider. Example: Okta, Google, Auth0 | | `social` | boolean | Is the connection a social provider (like Google, Microsoft, GitHub etc) or an enterprise connection. | | `provider_raw_attributes` | object | key-value map of all the raw attributes received from the connection provider as-is | --- # DOCUMENT BOUNDARY --- # Error handling during single sign-on > Learn how to identify and resolve common single sign-on errors in Scalekit, ensuring a seamless authentication experience for your users Reference of error codes and how to handle them When users attempt to log in via single sign-on (SSO) using Scalekit, any issues encountered will result in error details being sent to your application’s redirect URI via the `error` and `error_description` query parameters. Proper error handling ensures a better user experience. ## Integration related errors [Section titled “Integration related errors”](#integration-related-errors) If there is any issue between Scalekit and your application, the following errors may occur: | Error | Error description | Possible resolution strategy | | ----------------------------------- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | ``` invalid_redirect_uri ``` | Redirect URI is not part of the pre-approved list of redirect URIs | Add the valid URL in the Scalekit dashboard before using it | | ``` invalid_connection_selector ``` | Missing `organization_id` (or) `connection_id` (or) `domain` (or) `provider` in the authorization URL | Include at least one of these parameters in the request | | ``` no_active_connections ``` | There are no active SSO connections configured to process the single sign-on request | Ensure active SSO connections are set up | | ``` connection_not_active ``` | The configured connection is not active | Enable the SSO connection in the Scalekit dashboard | | ``` no_configured_connections ``` | No active SSO connections configured | Ensure active SSO connections are set up | | ``` invalid_organization_id ``` | Invalid organization ID | Verify and use a valid organization ID | | ``` invalid_connection_id ``` | Invalid connection ID | Verify and use a valid connection ID | | ``` domain_not_found ``` | No domain specified for the SSO connection(s) | Check domain configuration in Scalekit dashboard | | ``` invalid_user_domain ``` | User’s domain not allowed for this SSO connection | Ensure user domain is part of the allowed domains list | | ``` invalid_client ``` | The client application is not recognized or not configured correctly | Verify the `client_id` value in your authorization URL | | ``` application_not_active ``` | The application is inactive | Enable the application in the Scalekit dashboard | | ``` invalid_request ``` | The authorization request contains invalid or missing parameters | Review the authorization URL parameters | | ``` unauthorized ``` | The request is unauthorized | Verify that valid credentials are being used | | ``` user_not_active ``` | The user account is inactive | Activate the user account or contact the IT admin | | ``` server_error ``` | *actual error description from the server* | This must be a rare occurrence. Please reach out to us via your private slack channel or [via email](mailto:support@scalekit.com) | ## SSO configuration related errors [Section titled “SSO configuration related errors”](#sso-configuration-related-errors) If SSO configuration issues arise, you will encounter the following errors: | Error code | Error description | Possible resolution strategy | | ------------------------------------ | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ``` mandatory_attribute_missing ``` | Missing mandatory user attributes | Ensure all the mandatory user attributes are configured properly | | ``` invalid_id_token ``` | Invalid ID token | Check the identity provider’s functioning | | ``` failed_to_exchange_token ``` | Token exchange failure due to incorrect `client_secret` | Update the `client_secret` with the correct value | | ``` user_info_retrieve_failed ``` | User info retrieval failed, possibly due to an incorrect `client_secret` or other issues | Update the `client_secret` with the correct value. If unsuccessful, investigate further. Please reach out to us via your private slack channel or [via email](mailto:support@scalekit.com) | | ``` invalid_saml_metadata ``` | Incorrect SAML metadata configuration | Update SAML metadata URL with the correct value | | ``` invalid_saml_response ``` | Invalid SAML response | Review and fix SAML configuration settings | | ``` invalid_saml_request ``` | The SAML request is invalid | Check the SAML configuration in both Scalekit and the identity provider | | ``` invalid_saml_form_params ``` | The SAML form parameters are invalid or malformed | Review the SAML response format from the identity provider | | ``` signature_validation_failed ``` | Failed signature validation | Review and update the ACS URL in the identity provider’s settings | | ``` invalid_acs_url ``` | Invalid ACS URL | Review and update the ACS URL in the identity provider’s settings | | ``` invalid_assertion_url ``` | The assertion URL in the SAML request is invalid | Verify and update the ACS URL in the identity provider’s settings | | ``` invalid_status ``` | Invalid status | Review and update the SAML configuration settings in the identity provider | | ``` malformed_saml_response ``` | Marshalling error | Ensure SAML response is properly formatted | | ``` assertion_expired ``` | Expired SAML assertion | We received an expired SAML assertion. This could be because of clock skew between the identity provider’s server and our servers. Please reach out to us via your private slack channel or [via email](mailto:support@scalekit.com) | | ``` response_expired ``` | Expired SAML response | We received an expired SAML response. This could be because of clock skew between the identity provider’s server and our servers. Please reach out to us via your private slack channel or [via email](mailto:support@scalekit.com) | | ``` authentication_not_completed ``` | The authentication flow was not completed | Ensure the user completes the login process in the identity provider | | ``` user_login_required ``` | User login is required to continue | Redirect the user to the login page to complete authentication | --- # DOCUMENT BOUNDARY --- # Contact Us > Get in touch with the Scalekit team for support, schedule a call, or find answers to frequently asked questions about our services. If you encounter issues that remain unresolved despite your best troubleshooting efforts and our rigorous testing, please reach out to the Scalekit team using the contact information provided below. We will respond as quickly as possible. ### Talk to a dev [Write to us](mailto:support@scalekit.com) | [Schedule a call](https://scalekit.com/demo) ### Slack Community [Join our Slack community](https://join.slack.com/t/scalekit-community/shared_invite/zt-3gsxwr4hc-0tvhwT2b_qgVSIZQBQCWRw) to reach out for support and ask questions. --- # DOCUMENT BOUNDARY --- # Agent connectors > Search connectors and tools for Slack, Google Workspace, Salesforce, and more. Search connectors and tools by name, category, or capability. Use this page to find a provider, open its docs, and see which tools your agents can call. Search connectors or tools… All categories (all)All auth types (all) ## Connectors [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/customsmartfhir.png)](/agentkit/connectors/customsmartfhir/) [SMART App on FHIRSMART On FHIR](/agentkit/connectors/customsmartfhir/) [SMART App on FHIR is a healthcare interoperability provider that enables secure access to electronic health records and clinical data using the SMART on...](/agentkit/connectors/customsmartfhir/) [scalekit81 tools](/agentkit/connectors/customsmartfhir/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/activepieces.svg)](/agentkit/connectors/activepiecesmcp/) [Activepieces MCPOAuth 2.1/DCR](/agentkit/connectors/activepiecesmcp/) [Connect to Activepieces MCP to trigger and manage no-code automation flows directly from your AI workflows.](/agentkit/connectors/activepiecesmcp/) [Vendor MCP44 tools](/agentkit/connectors/activepiecesmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adobe.svg)](/agentkit/connectors/adobemarketingagentmcp/) [Adobe Marketing Agent MCPOAuth 2.1/DCR](/agentkit/connectors/adobemarketingagentmcp/) [Connect to Adobe Marketing Cloud. Manage campaigns, analytics, and journeys using a natural-language AI assistant.](/agentkit/connectors/adobemarketingagentmcp/) [Vendor MCP12 tools](/agentkit/connectors/adobemarketingagentmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/advancedmd.png)](/agentkit/connectors/advancedmd/) [AdvancedMDSMART On FHIR](/agentkit/connectors/advancedmd/) [AdvancedMD is a cloud-based medical practice management and electronic health record (EHR) platform. This connector uses the SMART on FHIR authorization...](/agentkit/connectors/advancedmd/) [scalekit89 tools](/agentkit/connectors/advancedmd/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adzviser.svg)](/agentkit/connectors/adzvisermcp/) [Adzviser MCPOAuth 2.1/DCR](/agentkit/connectors/adzvisermcp/) [Connect to Adzviser MCP to query real-time marketing analytics across 46+ platforms - Google Ads, Facebook Ads, GA4, TikTok, LinkedIn, and more - from a...](/agentkit/connectors/adzvisermcp/) [Vendor MCP58 tools](/agentkit/connectors/adzvisermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/affinda.svg)](/agentkit/connectors/affindamcp/) [Affinda MCPOAuth 2.1/DCR](/agentkit/connectors/affindamcp/) [AI-powered document processing platform that extracts, validates, and integrates structured data from invoices, resumes, contracts, and custom document...](/agentkit/connectors/affindamcp/) [Vendor MCP85 tools](/agentkit/connectors/affindamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/affinity.svg)](/agentkit/connectors/affinity/) [AffinityBearer Token](/agentkit/connectors/affinity/) [Connect to Affinity relationship intelligence CRM to manage deal flow, relationships, pipeline opportunities, and network connections for private capital...](/agentkit/connectors/affinity/) [scalekit49 tools](/agentkit/connectors/affinity/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agencyanalytics.svg)](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics MCPOAuth 2.1/DCR](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics is a marketing reporting platform that enables digital agencies to monitor SEO, PPC, social media, and other channel performance in...](/agentkit/connectors/agencyanalyticsmcp/) [Vendor MCP35 tools](/agentkit/connectors/agencyanalyticsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agentmail.svg)](/agentkit/connectors/agentmailmcp/) [Agentmail MCPOAuth 2.1/DCR](/agentkit/connectors/agentmailmcp/) [Connect to Agentmail MCP. Manage inboxes, send and receive email, handle drafts, threads, and attachments from your AI workflows.](/agentkit/connectors/agentmailmcp/) [Vendor MCP26 tools](/agentkit/connectors/agentmailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/ahrefs.svg)](/agentkit/connectors/ahrefsmcp/) [Ahrefs MCPOAuth 2.1/DCR](/agentkit/connectors/ahrefsmcp/) [Connect to Ahrefs MCP to access SEO data including backlinks, keyword research, site audits, rank tracking, and web analytics directly from your AI...](/agentkit/connectors/ahrefsmcp/) [Vendor MCP134 tools](/agentkit/connectors/ahrefsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airbyte.svg)](/agentkit/connectors/airbytemcp/) [Airbyte MCPOAuth 2.1/DCR](/agentkit/connectors/airbytemcp/) [Connect to Airbyte's MCP server to manage data pipelines, sources, destinations, and connections for your data integration workflows.](/agentkit/connectors/airbytemcp/) [Vendor MCP20 tools](/agentkit/connectors/airbytemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airops.svg)](/agentkit/connectors/airopsmcp/) [Airops MCPAPI Key](/agentkit/connectors/airopsmcp/) [Connect to AirOps MCP. Manage brand kits, run AI-powered analytics, track AEO citations, and automate content workflows from your AI agents.](/agentkit/connectors/airopsmcp/) [Vendor MCP91 tools](/agentkit/connectors/airopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airparser.svg)](/agentkit/connectors/airparsermcp/) [Airparser MCPOAuth 2.1/DCR](/agentkit/connectors/airparsermcp/) [AI-powered document parser that extracts structured data from PDFs, emails, and other documents.](/agentkit/connectors/airparsermcp/) [Vendor MCP17 tools](/agentkit/connectors/airparsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtable/) [AirtableOAuth 2.0](/agentkit/connectors/airtable/) [Connect to Airtable. Manage databases, tables, records, and collaborate on structured data](/agentkit/connectors/airtable/) [scalekit26 tools](/agentkit/connectors/airtable/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtablemcp/) [Airtable MCPOAuth 2.1/DCR](/agentkit/connectors/airtablemcp/) [Connect to Airtable MCP. Manage bases, tables, records, views, fields, and automations from your AI workflows.](/agentkit/connectors/airtablemcp/) [Vendor MCP43 tools](/agentkit/connectors/airtablemcp/) [![](https://akta.pro/favicon.ico?favicon.0_ooe5s20rw4w.ico)](/agentkit/connectors/aktapro/) [Akta ProAPI Key](/agentkit/connectors/aktapro/) [Connect to Akta Pro to search and monitor company news signals, including sentiment, entities, and industry classification, for sales and market...](/agentkit/connectors/aktapro/) [scalekit1 tool](/agentkit/connectors/aktapro/) [![](https://akta.pro/favicon.ico?favicon.0_ooe5s20rw4w.ico)](/agentkit/connectors/aktapromcp/) [Akta Pro MCPAPI Key](/agentkit/connectors/aktapromcp/) [Connect to Akta Pro MCP to search company news signals, check account status, and access sales intelligence tools directly from your AI agents.](/agentkit/connectors/aktapromcp/) [Vendor MCP17 tools](/agentkit/connectors/aktapromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/alphaxiv.svg)](/agentkit/connectors/alphaxivmcp/) [AlphaXiv MCPOAuth 2.1/DCR](/agentkit/connectors/alphaxivmcp/) [Connect to AlphaXiv MCP to search and retrieve arXiv research papers, abstracts, authors, and citations from your AI workflows.](/agentkit/connectors/alphaxivmcp/) [Vendor MCP18 tools](/agentkit/connectors/alphaxivmcp/) [![](https://docs.amplemarket.com/mintlify-assets/_mintlify/favicons/amplemarket-50/mca-0KUOMtPMXsSB/_generated/favicon-dark/favicon-32x32.png)](/agentkit/connectors/amplemarket/) [AmplemarketBearer Token](/agentkit/connectors/amplemarket/) [Connect to Amplemarket, an AI-powered sales engagement platform, to search and enrich B2B leads, manage email/LinkedIn outreach sequences, and score...](/agentkit/connectors/amplemarket/) [scalekit47 tools](/agentkit/connectors/amplemarket/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/amplitude.svg)](/agentkit/connectors/amplitudeanalytics/) [Amplitude AnalyticsAPI Key + Secret Key](/agentkit/connectors/amplitudeanalytics/) [Connect to Amplitude's analytics REST APIs: event segmentation, funnels, cohorts, taxonomy, chart annotations, session replay, export, releases, streaming...](/agentkit/connectors/amplitudeanalytics/) [scalekit74 tools](/agentkit/connectors/amplitudeanalytics/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/amplitude.svg)](/agentkit/connectors/amplitudeexperimentmanagement/) [Amplitude Experiment ManagementBearer Token](/agentkit/connectors/amplitudeexperimentmanagement/) [Manage Amplitude Experiment feature flags, experiments, mutex groups, holdouts, and deployments. Separate connector from Experiment Evaluation (real-time...](/agentkit/connectors/amplitudeexperimentmanagement/) [scalekit57 tools](/agentkit/connectors/amplitudeexperimentmanagement/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anakin.svg)](/agentkit/connectors/anakinmcp/) [Anakin MCPOAuth 2.1/DCR](/agentkit/connectors/anakinmcp/) [Anakin is an AI platform and marketplace that lets you build, deploy, and access a wide range of AI tools and automated workflows. This MCP connector...](/agentkit/connectors/anakinmcp/) [Vendor MCP21 tools](/agentkit/connectors/anakinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anchorbrowser.svg)](/agentkit/connectors/anchorbrowsermcp/) [Anchor Browser MCPOAuth 2.1/DCR](/agentkit/connectors/anchorbrowsermcp/) [Connect to Anchor Browser MCP to run cloud browser automation, control live browser sessions, extract web data, and let AI agents browse and act on the...](/agentkit/connectors/anchorbrowsermcp/) [Vendor MCP25 tools](/agentkit/connectors/anchorbrowsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apify.svg)](/agentkit/connectors/apifymcp/) [Apify MCPBearer Token](/agentkit/connectors/apifymcp/) [Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows.](/agentkit/connectors/apifymcp/) [Vendor MCP11 tools](/agentkit/connectors/apifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apollo/) [ApolloOAuth 2.0](/agentkit/connectors/apollo/) [Connect to Apollo.io to search and enrich B2B contacts and accounts, manage CRM contacts, and automate outreach sequences.](/agentkit/connectors/apollo/) [scalekit75 tools](/agentkit/connectors/apollo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apolloapikey/) [Apollo (API Key)API Key](/agentkit/connectors/apolloapikey/) [Connect to Apollo.io using a master API key to search and enrich B2B contacts and accounts, manage CRM records, sequences, tasks, and deals, and access...](/agentkit/connectors/apolloapikey/) [scalekit80 tools](/agentkit/connectors/apolloapikey/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apollomcp/) [Apollo MCPOAuth 2.1/DCR](/agentkit/connectors/apollomcp/) [Connect to Apollo MCP to search B2B contacts, enrich people and organizations, manage CRM records, and enroll prospects in sequences.](/agentkit/connectors/apollomcp/) [Vendor MCP61 tools](/agentkit/connectors/apollomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/appsignal.svg)](/agentkit/connectors/appsignalmcp/) [AppSignal MCPOAuth 2.1/DCR](/agentkit/connectors/appsignalmcp/) [AppSignal is an application monitoring and performance management platform providing error tracking, performance monitoring, and alerting for Ruby...](/agentkit/connectors/appsignalmcp/) [Vendor MCP25 tools](/agentkit/connectors/appsignalmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asana/) [AsanaOAuth 2.0](/agentkit/connectors/asana/) [Connect to Asana. Manage tasks, projects, teams, and workflow automation](/agentkit/connectors/asana/) [scalekit210 tools](/agentkit/connectors/asana/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asanamcp/) [Asana MCPOAuth 2.1](/agentkit/connectors/asanamcp/) [Connect to Asana MCP server to manage tasks, projects, and teams directly from your AI workflows.](/agentkit/connectors/asanamcp/) [Vendor MCP38 tools](/agentkit/connectors/asanamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/atlassian.svg)](/agentkit/connectors/atlassianmcp/) [Atlassian Rovo MCPOAuth 2.1/DCR](/agentkit/connectors/atlassianmcp/) [Connect to Atlassian Rovo MCP server to manage Jira issues, Confluence pages, and Compass components directly from your AI workflows.](/agentkit/connectors/atlassianmcp/) [Vendor MCP39 tools](/agentkit/connectors/atlassianmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attention.svg)](/agentkit/connectors/attention/) [AttentionAPI Key](/agentkit/connectors/attention/) [Connect to Attention for AI insights, conversations, teams, and workflows](/agentkit/connectors/attention/) [scalekit28 tools](/agentkit/connectors/attention/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attio.svg)](/agentkit/connectors/attio/) [AttioOAuth 2.0](/agentkit/connectors/attio/) [Connect to Attio CRM to manage contacts, companies, deals, notes, tasks, and lists with a modern relationship management platform.](/agentkit/connectors/attio/) [scalekit109 tools](/agentkit/connectors/attio/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attio.svg)](/agentkit/connectors/attiomcp/) [Attio MCPOAuth 2.1/DCR](/agentkit/connectors/attiomcp/) [Connect to Attio MCP. Access and manage CRM records, lists, notes, tasks, emails, and workspace data across people, companies, and deals.](/agentkit/connectors/attiomcp/) [Vendor MCP38 tools](/agentkit/connectors/attiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/redshift.svg)](/agentkit/connectors/redshift/) [AWS RedshiftTrusted IDP](/agentkit/connectors/redshift/) [Amazon Redshift is a fully managed cloud data warehouse that enables fast, cost-effective analysis of structured and semi-structured data at scale.](/agentkit/connectors/redshift/) [scalekit10 tools](/agentkit/connectors/redshift/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/axiom.svg)](/agentkit/connectors/axiommcp/) [Axiom MCPOAuth 2.1/DCR](/agentkit/connectors/axiommcp/) [Axiom is a cloud-native data analytics and observability platform for ingesting, storing, and querying logs, events, traces, and metrics at scale. The MCP...](/agentkit/connectors/axiommcp/) [Vendor MCP26 tools](/agentkit/connectors/axiommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/betterstack.svg)](/agentkit/connectors/betterstackmcp/) [Betterstack MCPOAuth 2.1/DCR](/agentkit/connectors/betterstackmcp/) [Monitor uptime, manage logs, and respond to incidents with Better Stack's observability platform.](/agentkit/connectors/betterstackmcp/) [Vendor MCP107 tools](/agentkit/connectors/betterstackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg)](/agentkit/connectors/bigqueryserviceaccount/) [BigQuery (Service Account)Service Account](/agentkit/connectors/bigqueryserviceaccount/) [Connect to Google BigQuery using a GCP service account for server-to-server authentication without user login.](/agentkit/connectors/bigqueryserviceaccount/) [scalekit26 tools](/agentkit/connectors/bigqueryserviceaccount/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biorendermcp.svg)](/agentkit/connectors/biorendermcp/) [Bio Render MCPOAuth 2.1/DCR](/agentkit/connectors/biorendermcp/) [Connect to BioRender MCP. Search BioRender's scientific icon and figure template libraries to build publication-ready biological illustrations.](/agentkit/connectors/biorendermcp/) [Vendor MCP2 tools](/agentkit/connectors/biorendermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biomni.svg)](/agentkit/connectors/biomnimcp/) [Biomni MCPOAuth 2.1/DCR](/agentkit/connectors/biomnimcp/) [Connect to Biomni MCP by phylo.bio, an AI biomedical research assistant. Analyze life-sciences data, interpret genomic variants, query curated databases...](/agentkit/connectors/biomnimcp/) [Vendor MCP12 tools](/agentkit/connectors/biomnimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitbucket.svg)](/agentkit/connectors/bitbucket/) [BitbucketOAuth 2.0](/agentkit/connectors/bitbucket/) [Connect to Bitbucket. Manage repositories, pipelines, pull requests, and code collaboration.](/agentkit/connectors/bitbucket/) [scalekit171 tools](/agentkit/connectors/bitbucket/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitly.svg)](/agentkit/connectors/bitlymcp/) [Bitly MCPOAuth 2.1/DCR](/agentkit/connectors/bitlymcp/) [Connect with Bitly MCP for URL shortening, link analytics, and branded links.](/agentkit/connectors/bitlymcp/) [Vendor MCP79 tools](/agentkit/connectors/bitlymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitquery.svg)](/agentkit/connectors/bitquerymcp/) [Bitquery MCPOAuth 2.1/DCR](/agentkit/connectors/bitquerymcp/) [Connect to Bitquery MCP. Query on-chain DEX trading data, token prices, OHLCV series, trader profiles, and trending tokens across multiple blockchains...](/agentkit/connectors/bitquerymcp/) [Vendor MCP123 tools](/agentkit/connectors/bitquerymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bonsai.svg)](/agentkit/connectors/bonsaimcp/) [Bonsai MCPOAuth 2.1/DCR](/agentkit/connectors/bonsaimcp/) [Connect to Bonsai, the all-in-one business management platform for freelancers and agencies. Manage projects, tasks, CRM contacts, deals, invoices, and...](/agentkit/connectors/bonsaimcp/) [Vendor MCP34 tools](/agentkit/connectors/bonsaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg)](/agentkit/connectors/box/) [BoxOAuth 2.0](/agentkit/connectors/box/) [Box is a cloud content management platform. Manage files, folders, users, groups, collaborations, tasks, comments, webhooks, search, and more using the...](/agentkit/connectors/box/) [scalekit102 tools](/agentkit/connectors/box/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg)](/agentkit/connectors/boxmcp/) [Box MCPOAuth 2.1](/agentkit/connectors/boxmcp/) [Connect to Box via MCP to manage files, folders, collaborations, users, groups, tasks, comments, and search content directly from your AI workflows.](/agentkit/connectors/boxmcp/) [Vendor MCP44 tools](/agentkit/connectors/boxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brandfetch.svg)](/agentkit/connectors/brandfetchmcp/) [Brandfetch MCPOAuth 2.1/DCR](/agentkit/connectors/brandfetchmcp/) [Connect to Brandfetch's MCP server to search, retrieve, and enrich brand data — logos, colors, fonts, and company details — directly from your AI...](/agentkit/connectors/brandfetchmcp/) [Vendor MCP7 tools](/agentkit/connectors/brandfetchmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brave.svg)](/agentkit/connectors/brave/) [Brave SearchAPI Key](/agentkit/connectors/brave/) [Connect to Brave Search to perform web, image, video, and news searches with privacy-focused results, plus AI-powered suggestions and spellcheck.](/agentkit/connectors/brave/) [scalekit18 tools](/agentkit/connectors/brave/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brevo.svg)](/agentkit/connectors/brevomcp/) [Brevo MCPOAuth 2.1/DCR](/agentkit/connectors/brevomcp/) [Connect to Brevo MCP. Manage email and SMS campaigns, transactional emails, contacts, lists, automations, and loyalty programs from your AI workflows.](/agentkit/connectors/brevomcp/) [Vendor MCP282 tools](/agentkit/connectors/brevomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bugsnag.svg)](/agentkit/connectors/bugsnagmcp/) [Bugsnag MCPOAuth 2.1/DCR](/agentkit/connectors/bugsnagmcp/) [Connect to Bugsnag MCP. Monitor errors, releases, traces, and span groups across your projects from your AI workflows.](/agentkit/connectors/bugsnagmcp/) [Vendor MCP19 tools](/agentkit/connectors/bugsnagmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/buildkite.svg)](/agentkit/connectors/buildkitemcp/) [Buildkite MCPOAuth 2.1/DCR](/agentkit/connectors/buildkitemcp/) [Connect to Buildkite MCP. Manage CI/CD pipelines, builds, agents, clusters, and test suites from your AI workflows.](/agentkit/connectors/buildkitemcp/) [Vendor MCP51 tools](/agentkit/connectors/buildkitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/builtwith.svg)](/agentkit/connectors/builtwithmcp/) [BuiltWith MCPBearer Token](/agentkit/connectors/builtwithmcp/) [BuiltWith tracks the technology stacks of millions of websites. The BuiltWith MCP server lets AI agents look up a site's technology profile, track...](/agentkit/connectors/builtwithmcp/) [Vendor MCP48 tools](/agentkit/connectors/builtwithmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cal.svg)](/agentkit/connectors/calmcp/) [Cal MCPOAuth 2.1/DCR](/agentkit/connectors/calmcp/) [Connect to Cal MCP. Manage bookings, event types, schedules, and availability from your AI workflows.](/agentkit/connectors/calmcp/) [Vendor MCP35 tools](/agentkit/connectors/calmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/calendly.svg)](/agentkit/connectors/calendly/) [CalendlyOAuth 2.0](/agentkit/connectors/calendly/) [Connect to Calendly. Access user profile, events, and scheduling workflows.](/agentkit/connectors/calendly/) [scalekit64 tools](/agentkit/connectors/calendly/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/calendly.svg)](/agentkit/connectors/calendlymcp/) [Calendly MCPOAuth 2.1/DCR](/agentkit/connectors/calendlymcp/) [Connect to the Calendly MCP server to manage scheduled events, invitees, event types, and availability directly from your AI workflows.](/agentkit/connectors/calendlymcp/) [Vendor MCP36 tools](/agentkit/connectors/calendlymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/candid.svg)](/agentkit/connectors/candidmcp/) [Candid MCPOAuth 2.1/DCR](/agentkit/connectors/candidmcp/) [Connect to Candid MCP. Search nonprofit organizations, explore philanthropic data, and classify social sector activities using Candid's knowledge base.](/agentkit/connectors/candidmcp/) [Vendor MCP6 tools](/agentkit/connectors/candidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/canva.svg)](/agentkit/connectors/canva/) [CanvaOAuth 2.0](/agentkit/connectors/canva/) [Connect to Canva's Connect API to manage designs, assets, folders, brand templates, comments, autofills, exports, and analytics on the user's behalf via...](/agentkit/connectors/canva/) [scalekit48 tools](/agentkit/connectors/canva/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carbone.svg)](/agentkit/connectors/carboneiomcp/) [Carbone.io MCPBearer Token](/agentkit/connectors/carboneiomcp/) [Connect to Carbone.io MCP. Upload templates, render documents by merging templates with JSON data, convert between 100+ formats, and manage template...](/agentkit/connectors/carboneiomcp/) [Vendor MCP11 tools](/agentkit/connectors/carboneiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carta.svg)](/agentkit/connectors/cartamcp/) [Carta MCPOAuth 2.1/DCR](/agentkit/connectors/cartamcp/) [Connect to Carta. Manage equity cap tables, fund administration, company accounts, and ownership data for venture-backed companies.](/agentkit/connectors/cartamcp/) [Vendor MCP18 tools](/agentkit/connectors/cartamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/catchr.svg)](/agentkit/connectors/catchrmcp/) [Catchr MCPOAuth 2.1/DCR](/agentkit/connectors/catchrmcp/) [Catchr is a data connector platform that syncs marketing and analytics data from ad platforms (Google Ads, Facebook Ads, etc.) to data warehouses and BI...](/agentkit/connectors/catchrmcp/) [Vendor MCP8 tools](/agentkit/connectors/catchrmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chilipiper.svg)](/agentkit/connectors/chilipipermcp/) [ChiliPiper MCPBearer Token](/agentkit/connectors/chilipipermcp/) [Connect to ChiliPiper MCP. Schedule meetings, manage routing rules, track distributions, and automate handoffs from your AI agents.](/agentkit/connectors/chilipipermcp/) [Vendor MCP156 tools](/agentkit/connectors/chilipipermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chorus.svg)](/agentkit/connectors/chorus/) [ChorusBasic Auth](/agentkit/connectors/chorus/) [Connect to Chorus.ai to sync calls, transcripts, conversation intelligence, and analytics.](/agentkit/connectors/chorus/) [scalekit9 tools](/agentkit/connectors/chorus/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/circleback.svg)](/agentkit/connectors/circlebackmcp/) [Circleback MCPOAuth 2.1/DCR](/agentkit/connectors/circlebackmcp/) [Circleback is an AI meeting notes and conversation intelligence platform. The Circleback MCP server provides a standardized interface that allows any...](/agentkit/connectors/circlebackmcp/) [Vendor MCP11 tools](/agentkit/connectors/circlebackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/claap.svg)](/agentkit/connectors/claapmcp/) [Claap MCPOAuth 2.1/DCR](/agentkit/connectors/claapmcp/) [Video collaboration platform for recording, sharing, and discussing async video clips — used for meeting recordings, product demos, feedback, and team...](/agentkit/connectors/claapmcp/) [Vendor MCP54 tools](/agentkit/connectors/claapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clari.svg)](/agentkit/connectors/clari_copilot/) [Clari CopilotAPI Key](/agentkit/connectors/clari_copilot/) [Connect to Clari Copilot for sales call transcripts, analytics, call data, and insights.](/agentkit/connectors/clari_copilot/) [scalekitComing soon](/agentkit/connectors/clari_copilot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clarify.svg)](/agentkit/connectors/clarifymcp/) [Clarify MCPOAuth 2.1/DCR](/agentkit/connectors/clarifymcp/) [Connect to Clarify MCP to manage CRM records, leads, campaigns, lists, and analytics directly from your AI workflows.](/agentkit/connectors/clarifymcp/) [Vendor MCP38 tools](/agentkit/connectors/clarifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clay.svg)](/agentkit/connectors/claymcp/) [Clay MCPOAuth 2.1/DCR](/agentkit/connectors/claymcp/) [Clay is a go-to-market (GTM) platform that unifies data sourcing from 150+ providers, AI-powered research agents, and workflow orchestration for sales and...](/agentkit/connectors/claymcp/) [Vendor MCP17 tools](/agentkit/connectors/claymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickhouse.svg)](/agentkit/connectors/clickhouse/) [Clickhouse MCPOAuth 2.1/DCR](/agentkit/connectors/clickhouse/) [Connect to ClickHouse MCP to query, analyze, and manage your ClickHouse databases directly from your AI workflows.](/agentkit/connectors/clickhouse/) [scalekit17 tools](/agentkit/connectors/clickhouse/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickup/) [ClickUpOAuth 2.0](/agentkit/connectors/clickup/) [Connect to ClickUp. Manage tasks, projects, workspaces, and team collaboration](/agentkit/connectors/clickup/) [scalekit99 tools](/agentkit/connectors/clickup/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickupmcp/) [ClickUp MCPOAuth 2.1/DCR](/agentkit/connectors/clickupmcp/) [Connect to ClickUp MCP to manage tasks, projects, spaces, and workspaces directly from your AI workflows.](/agentkit/connectors/clickupmcp/) [Vendor MCP57 tools](/agentkit/connectors/clickupmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/close.svg)](/agentkit/connectors/close/) [CloseOAuth 2.0](/agentkit/connectors/close/) [Connect to Close CRM. Manage leads, contacts, opportunities, tasks, activities, and sales workflows](/agentkit/connectors/close/) [scalekit103 tools](/agentkit/connectors/close/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/close.svg)](/agentkit/connectors/closemcp/) [Close MCPOAuth 2.1/DCR](/agentkit/connectors/closemcp/) [Close is a CRM and sales platform. The Close MCP server provides a standardized interface that allows any compatible AI model or agent to access Close CRM...](/agentkit/connectors/closemcp/) [Vendor MCP105 tools](/agentkit/connectors/closemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudflare/) [CloudflareOAuth 2.0](/agentkit/connectors/cloudflare/) [Cloudflare is a cloud platform providing DNS management, CDN, security, and networking services. This connector enables automated management of zones, DNS...](/agentkit/connectors/cloudflare/) [scalekit31 tools](/agentkit/connectors/cloudflare/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudfaremcp/) [Cloudflare MCPOAuth 2.1/DCR](/agentkit/connectors/cloudfaremcp/) [Connect to Cloudflare MCP to manage your Cloudflare account — execute API calls, search the OpenAPI spec, and interact with Workers, R2, D1, KV, and all...](/agentkit/connectors/cloudfaremcp/) [Vendor MCP3 tools](/agentkit/connectors/cloudfaremcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudinary.svg)](/agentkit/connectors/cloudinarymcp/) [Cloudinary MCPOAuth 2.1/DCR](/agentkit/connectors/cloudinarymcp/) [Connects AI agents to Cloudinary's asset management platform, enabling upload, search, transformation, and organization of media assets through natural...](/agentkit/connectors/cloudinarymcp/) [Vendor MCP30 tools](/agentkit/connectors/cloudinarymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudpress.svg)](/agentkit/connectors/cloudpressmcp/) [Cloudpress MCPOAuth 2.1/DCR](/agentkit/connectors/cloudpressmcp/) [Cloudpress is a managed WordPress hosting platform built for the AI era. Its MCP server lets AI agents manage sites, domains, DNS, security rules...](/agentkit/connectors/cloudpressmcp/) [Vendor MCP66 tools](/agentkit/connectors/cloudpressmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cognee.svg)](/agentkit/connectors/cognee/) [CogneeAPI Key](/agentkit/connectors/cognee/) [Connect to Cognee, an AI memory engine for agents. Remember data into a knowledge graph, recall it with semantic search, improve stored memory, and forget...](/agentkit/connectors/cognee/) [scalekit18 tools](/agentkit/connectors/cognee/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/coinmarketcap.svg)](/agentkit/connectors/coinmarketcapmcp/) [CoinMarketCap MCPOAuth 2.1/DCR](/agentkit/connectors/coinmarketcapmcp/) [Connect to CoinMarketCap MCP. Access real-time crypto quotes, market metrics, technical analysis, trending narratives, and news from your AI workflows.](/agentkit/connectors/coinmarketcapmcp/) [Vendor MCP14 tools](/agentkit/connectors/coinmarketcapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/commonroom.svg)](/agentkit/connectors/commonroommcp/) [Commonroom MCPOAuth 2.1/DCR](/agentkit/connectors/commonroommcp/) [Connect to Common Room MCP to manage community members, objects, and feedback data directly from your AI workflows.](/agentkit/connectors/commonroommcp/) [Vendor MCP5 tools](/agentkit/connectors/commonroommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/confluence.svg)](/agentkit/connectors/confluence/) [ConfluenceOAuth 2.0](/agentkit/connectors/confluence/) [Connect to Confluence. Manage spaces, pages, content, and team collaboration](/agentkit/connectors/confluence/) [scalekit147 tools](/agentkit/connectors/confluence/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/contentful.svg)](/agentkit/connectors/contentfulmcp/) [Contentful MCPOAuth 2.1/DCR](/agentkit/connectors/contentfulmcp/) [Connect to Contentful MCP. Manage spaces, entries, assets, content types, and taxonomies in your Contentful CMS from AI workflows.](/agentkit/connectors/contentfulmcp/) [Vendor MCP70 tools](/agentkit/connectors/contentfulmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/context7.svg)](/agentkit/connectors/context7mcp/) [Context7 MCPAPI Key](/agentkit/connectors/context7mcp/) [Connect to Context7 MCP to fetch up-to-date, version-specific library documentation and code examples directly from the source.](/agentkit/connectors/context7mcp/) [Vendor MCP2 tools](/agentkit/connectors/context7mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/conversiontools.svg)](/agentkit/connectors/conversiontoolsmcp/) [Conversion Tools MCPOAuth 2.1/DCR](/agentkit/connectors/conversiontoolsmcp/) [Connect to Conversion Tools MCP. Convert files between 140+ formats including documents, images, audio, video, and data files from your AI workflows.](/agentkit/connectors/conversiontoolsmcp/) [Vendor MCP23 tools](/agentkit/connectors/conversiontoolsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/convertapi.svg)](/agentkit/connectors/convertapimcp/) [ConvertAPI MCPOAuth 2.1/DCR](/agentkit/connectors/convertapimcp/) [Connect to ConvertAPI MCP. Convert, merge, split, and transform files across 200+ formats including PDF, Word, Excel, images, and more.](/agentkit/connectors/convertapimcp/) [Vendor MCP5 tools](/agentkit/connectors/convertapimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/crossbeam.svg)](/agentkit/connectors/crossbeammcp/) [Crossbeam MCPOAuth 2.1/DCR](/agentkit/connectors/crossbeammcp/) [Connect to Crossbeam MCP. Discover partner account overlaps, surface ecosystem activity, get partner and account context, and access co-selling...](/agentkit/connectors/crossbeammcp/) [Vendor MCP9 tools](/agentkit/connectors/crossbeammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/crustdata.svg)](/agentkit/connectors/crustdatamcp/) [Crustdata MCPOAuth 2.1/DCR](/agentkit/connectors/crustdatamcp/) [People and company intelligence platform for candidate sourcing, sales prospecting, and talent intelligence. Provides real-time data on professionals...](/agentkit/connectors/crustdatamcp/) [Vendor MCP68 tools](/agentkit/connectors/crustdatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/customerio.svg)](/agentkit/connectors/customeriomcp/) [Customer.io MCPOAuth 2.1/DCR](/agentkit/connectors/customeriomcp/) [Connect to Customer.io MCP to manage customers, campaigns, and events](/agentkit/connectors/customeriomcp/) [Vendor MCP8 tools](/agentkit/connectors/customeriomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dartai.svg)](/agentkit/connectors/dartaimcp/) [Dart AI MCPOAuth 2.1/DCR](/agentkit/connectors/dartaimcp/) [AI-native project management tool for task and document management with deep AI integration.](/agentkit/connectors/dartaimcp/) [Vendor MCP29 tools](/agentkit/connectors/dartaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databox.svg)](/agentkit/connectors/databoxmcp/) [Databox MCPOAuth 2.1/DCR](/agentkit/connectors/databoxmcp/) [Connect to Databox MCP. Query metrics, manage dashboards, and push custom data to your Databox analytics and reporting platform.](/agentkit/connectors/databoxmcp/) [Vendor MCP19 tools](/agentkit/connectors/databoxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databricks-1.svg)](/agentkit/connectors/databricksworkspace/) [Databricks WorkspaceService Principal (OAuth 2.0)](/agentkit/connectors/databricksworkspace/) [Connect to Databricks Workspace APIs using a Service Principal with OAuth 2.0 client credentials to manage clusters, jobs, notebooks, SQL, and more.](/agentkit/connectors/databricksworkspace/) [scalekit53 tools](/agentkit/connectors/databricksworkspace/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/datadog.svg)](/agentkit/connectors/datadog/) [DatadogAPI Key](/agentkit/connectors/datadog/) [Connect to Datadog to monitor metrics, logs, traces, dashboards, monitors, incidents, SLOs, synthetics, and security signals across your infrastructure.](/agentkit/connectors/datadog/) [scalekit105 tools](/agentkit/connectors/datadog/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dataforseo.svg)](/agentkit/connectors/dataforseomcp/) [Dataforseo MCPOAuth 2.1/DCR](/agentkit/connectors/dataforseomcp/) [Connect to DataForSEO. Access real-time SEO data including SERP results, keyword analytics, backlinks analysis, domain technologies, and AI visibility...](/agentkit/connectors/dataforseomcp/) [Vendor MCP90 tools](/agentkit/connectors/dataforseomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deel.svg)](/agentkit/connectors/deelmcp/) [Deel MCPOAuth 2.1/DCR](/agentkit/connectors/deelmcp/) [Global HR and payroll platform for hiring, paying, and managing international employees and contractors with built-in compliance.](/agentkit/connectors/deelmcp/) [Vendor MCP355 tools](/agentkit/connectors/deelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deepgram.svg)](/agentkit/connectors/deepgrammcp/) [Deepgram MCPOAuth 2.1/DCR](/agentkit/connectors/deepgrammcp/) [Connect to Deepgram MCP. Transcribe audio, generate speech, and manage transcription projects using Deepgram's AI-powered speech recognition API.](/agentkit/connectors/deepgrammcp/) [Vendor MCP1 tool](/agentkit/connectors/deepgrammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deepl.svg)](/agentkit/connectors/deeplmcp/) [DeepL MCPOAuth 2.1/DCR](/agentkit/connectors/deeplmcp/) [Connect to DeepL's MCP server to translate and rephrase text, correct grammar, translate documents, and manage glossaries and writing styles.](/agentkit/connectors/deeplmcp/) [Vendor MCP8 tools](/agentkit/connectors/deeplmcp/) [![](https://deepwiki.com/favicon.ico)](/agentkit/connectors/deepwikimcp/) [DeepWikiNo Auth](/agentkit/connectors/deepwikimcp/) [Connect to DeepWiki MCP to ask questions about and read AI-generated documentation for public GitHub repositories directly from your AI workflows.](/agentkit/connectors/deepwikimcp/) [Vendor MCP3 tools](/agentkit/connectors/deepwikimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/descript.svg)](/agentkit/connectors/descriptmcp/) [Descript MCPOAuth 2.1/DCR](/agentkit/connectors/descriptmcp/) [Connect to Descript MCP. Import media, export transcripts, publish projects, run AI editing agents, and manage jobs from your AI workflows.](/agentkit/connectors/descriptmcp/) [Vendor MCP14 tools](/agentkit/connectors/descriptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devrev.svg)](/agentkit/connectors/devrevmcp/) [Dev Rev MCPBearer Token](/agentkit/connectors/devrevmcp/) [Connect to DevRev MCP. Manage issues, work items, conversations, and customer data in the DevRev product development platform.](/agentkit/connectors/devrevmcp/) [Vendor MCP13 tools](/agentkit/connectors/devrevmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devin.svg)](/agentkit/connectors/devinmcp/) [Devin MCPBearer Token](/agentkit/connectors/devinmcp/) [Connect to Devin MCP. Create and manage AI coding sessions, interact with Devin agents, manage playbooks and schedules, and browse repository wikis from...](/agentkit/connectors/devinmcp/) [Vendor MCP19 tools](/agentkit/connectors/devinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/diarize.svg)](/agentkit/connectors/diarize/) [DiarizeBearer Token](/agentkit/connectors/diarize/) [Connect to Diarize to transcribe and diarize audio and video content from YouTube, X, Instagram, and TikTok. Submit transcription jobs and retrieve...](/agentkit/connectors/diarize/) [scalekit3 tools](/agentkit/connectors/diarize/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/digits.svg)](/agentkit/connectors/digitsmcp/) [Digits MCPOAuth 2.1/DCR](/agentkit/connectors/digitsmcp/) [Digits is an AI-powered business finance platform. This MCP connector gives AI agents read-only access to your Digits data — transactions, financial...](/agentkit/connectors/digitsmcp/) [Vendor MCP12 tools](/agentkit/connectors/digitsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/discord.svg)](/agentkit/connectors/discord/) [DiscordOAuth 2.0](/agentkit/connectors/discord/) [Connect to Discord. Read user profile, guilds, roles, manage bots, and perform interactions.](/agentkit/connectors/discord/) [scalekit34 tools](/agentkit/connectors/discord/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/discord.svg)](/agentkit/connectors/discordbot/) [Discord BotAPI Key](/agentkit/connectors/discordbot/) [Connect to Discord as a bot. Manage guilds, channels, members, messages, roles, webhooks, and more using a Discord Bot Token.](/agentkit/connectors/discordbot/) [scalekit221 tools](/agentkit/connectors/discordbot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/docsautomator.svg)](/agentkit/connectors/docsautomatormcp/) [Docsautomator MCPOAuth 2.1/DCR](/agentkit/connectors/docsautomatormcp/) [Connect to DocsAutomator MCP. Generate documents and PDFs from templates using your data, automating document creation workflows.](/agentkit/connectors/docsautomatormcp/) [Vendor MCP20 tools](/agentkit/connectors/docsautomatormcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dovetail.svg)](/agentkit/connectors/dovetailmcp/) [Dovetail MCPBearer Token](/agentkit/connectors/dovetailmcp/) [Connect to Dovetail, the AI-native UX research platform. Access projects, insights, and data from your AI workflows.](/agentkit/connectors/dovetailmcp/) [Vendor MCP44 tools](/agentkit/connectors/dovetailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/drop_box.svg)](/agentkit/connectors/dropbox/) [DropboxOAuth 2.0](/agentkit/connectors/dropbox/) [Connect to Dropbox. Manage files, folders, sharing, and cloud storage workflows](/agentkit/connectors/dropbox/) [scalekit53 tools](/agentkit/connectors/dropbox/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/drop_box.svg)](/agentkit/connectors/dropboxmcp/) [Dropbox MCPOAuth 2.1](/agentkit/connectors/dropboxmcp/) [Connect to Dropbox. Manage files and folders, create shared links, search content, and handle file requests from your AI workflows.](/agentkit/connectors/dropboxmcp/) [Vendor MCP25 tools](/agentkit/connectors/dropboxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dropcontact.svg)](/agentkit/connectors/dropcontactmcp/) [Dropcontact MCPOAuth 2.1/DCR](/agentkit/connectors/dropcontactmcp/) [B2B contact enrichment and email verification platform that finds, verifies, and enriches professional email addresses and company data.](/agentkit/connectors/dropcontactmcp/) [Vendor MCP6 tools](/agentkit/connectors/dropcontactmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dynamo.svg)](/agentkit/connectors/dynamo/) [Dynamo SoftwareBearer Token](/agentkit/connectors/dynamo/) [Connect to Dynamo Software API to access investment management, CRM, and reporting data.](/agentkit/connectors/dynamo/) [scalekit36 tools](/agentkit/connectors/dynamo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/echtpost.svg)](/agentkit/connectors/echtpostmcp/) [Echtpost MCPOAuth 2.1/DCR](/agentkit/connectors/echtpostmcp/) [Connect to Echtpost MCP. Send physical postcards and letters programmatically via the Echtpost API.](/agentkit/connectors/echtpostmcp/) [Vendor MCP22 tools](/agentkit/connectors/echtpostmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eden.svg)](/agentkit/connectors/edenmcp/) [Eden MCPOAuth 2.1/DCR](/agentkit/connectors/edenmcp/) [Eden is an AI-powered content creation platform that discovers viral trends across 3M+ social media posts and helps creators generate content in their...](/agentkit/connectors/edenmcp/) [Vendor MCP84 tools](/agentkit/connectors/edenmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eodhd.svg)](/agentkit/connectors/eodhdmcp/) [EODHD MCPOAuth 2.1/DCR](/agentkit/connectors/eodhdmcp/) [EODHD (End of Day Historical Data) provides comprehensive financial market data including end-of-day stock prices, historical OHLCV data, fundamentals...](/agentkit/connectors/eodhdmcp/) [Vendor MCP91 tools](/agentkit/connectors/eodhdmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eracontext.svg)](/agentkit/connectors/eracontextmcp/) [Era Context MCPOAuth 2.1/DCR](/agentkit/connectors/eracontextmcp/) [Connect to Era Context MCP. Access personal finance data including transactions, accounts, spending insights, and AI-powered financial knowledge from Era.](/agentkit/connectors/eracontextmcp/) [Vendor MCP51 tools](/agentkit/connectors/eracontextmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eraser.svg)](/agentkit/connectors/erasermcp/) [Eraser MCPOAuth 2.1/DCR](/agentkit/connectors/erasermcp/) [Connect to Eraser MCP. Create and edit diagrams, flowcharts, and technical documentation using Eraser's AI-powered diagramming tools.](/agentkit/connectors/erasermcp/) [Vendor MCP42 tools](/agentkit/connectors/erasermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/evertrace.png)](/agentkit/connectors/evertrace/) [Evertrace AIBearer Token](/agentkit/connectors/evertrace/) [Connect to evertrace.ai to search and manage talent signals, saved searches, and lists. Access rich professional profiles with scoring, experiences, and...](/agentkit/connectors/evertrace/) [scalekit26 tools](/agentkit/connectors/evertrace/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/exa/) [ExaAPI Key](/agentkit/connectors/exa/) [Connect to Exa to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, run in-depth...](/agentkit/connectors/exa/) [scalekit21 tools](/agentkit/connectors/exa/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/examcp/) [Exa MCPAPI Key](/agentkit/connectors/examcp/) [Connect to Exa MCP to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, and run...](/agentkit/connectors/examcp/) [Vendor MCP2 tools](/agentkit/connectors/examcp/) [![](https://docs.excalidraw.com/img/logo.svg)](/agentkit/connectors/excalidrawmcp/) [Excalidraw MCPBearer Token](/agentkit/connectors/excalidrawmcp/) [Excalidraw+ is a collaborative whiteboard and diagramming platform. The Excalidraw MCP server lets AI agents manage scenes, collections, workspaces...](/agentkit/connectors/excalidrawmcp/) [Vendor MCP29 tools](/agentkit/connectors/excalidrawmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/expo.svg)](/agentkit/connectors/expomcp/) [Expo MCPOAuth 2.1/DCR](/agentkit/connectors/expomcp/) [Expo is a platform for building universal React Native apps; its MCP server exposes developer services including EAS builds, submissions, and project...](/agentkit/connectors/expomcp/) [Vendor MCP24 tools](/agentkit/connectors/expomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathom/) [FathomAPI Key](/agentkit/connectors/fathom/) [Connect to Fathom AI meeting assistant. Record, transcribe, and summarize meetings with AI-powered insights](/agentkit/connectors/fathom/) [scalekit11 tools](/agentkit/connectors/fathom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathommcp/) [Fathom MCPOAuth 2.1/DCR](/agentkit/connectors/fathommcp/) [Connect to Fathom MCP to access AI meeting notes, summaries, transcripts, and recordings from your AI workflows.](/agentkit/connectors/fathommcp/) [Vendor MCP9 tools](/agentkit/connectors/fathommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fellowai.svg)](/agentkit/connectors/fellowaimcp/) [FellowAI MCPOAuth 2.1/DCR](/agentkit/connectors/fellowaimcp/) [Connect to Fellow.ai MCP to manage meeting notes, action items, agendas, and team collaboration workflows directly from your AI agent.](/agentkit/connectors/fellowaimcp/) [Vendor MCP7 tools](/agentkit/connectors/fellowaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/felt.svg)](/agentkit/connectors/feltmcp/) [FeltOAuth 2.1/DCR](/agentkit/connectors/feltmcp/) [Connect to Felt, a cloud-native GIS and mapping platform, to manage maps, layers, and geospatial data, query connected spatial databases, and collaborate...](/agentkit/connectors/feltmcp/) [Vendor MCP44 tools](/agentkit/connectors/feltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fever.svg)](/agentkit/connectors/fevermcp/) [Fever MCPOAuth 2.1/DCR](/agentkit/connectors/fevermcp/) [Fever is a live entertainment discovery platform. This MCP connector gives AI assistants direct access to Fever's global event catalog — search events by...](/agentkit/connectors/fevermcp/) [Vendor MCP2 tools](/agentkit/connectors/fevermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fibery.svg)](/agentkit/connectors/fiberymcp/) [Fibery MCPOAuth 2.1/DCR](/agentkit/connectors/fiberymcp/) [Connect to Fibery MCP. Query, create, and update entities across your Fibery workspace using the Fibery API and AI assistant.](/agentkit/connectors/fiberymcp/) [Vendor MCP80 tools](/agentkit/connectors/fiberymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/figma.svg)](/agentkit/connectors/figma/) [FigmaOAuth 2.0](/agentkit/connectors/figma/) [Connect to Figma to access user files, teams, projects, and design metadata via OAuth 2.0](/agentkit/connectors/figma/) [scalekit54 tools](/agentkit/connectors/figma/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/financialdatasets.svg)](/agentkit/connectors/financialdatasetsmcp/) [Financial Datasets MCPOAuth 2.1/DCR](/agentkit/connectors/financialdatasetsmcp/) [Financial Datasets provides an MCP interface to financial data APIs covering stock prices, financial statements, earnings, insider trades, and...](/agentkit/connectors/financialdatasetsmcp/) [Vendor MCP27 tools](/agentkit/connectors/financialdatasetsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/firecrawl.svg)](/agentkit/connectors/firecrawlmcp/) [Firecrawl MCPBearer Token](/agentkit/connectors/firecrawlmcp/) [Connect to Firecrawl MCP. Scrape, crawl, search, extract structured data, and monitor websites using Firecrawl's AI-powered web scraping API.](/agentkit/connectors/firecrawlmcp/) [Vendor MCP26 tools](/agentkit/connectors/firecrawlmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fireflies.svg)](/agentkit/connectors/firefliesmcp/) [Fireflies MCPOAuth 2.1/DCR](/agentkit/connectors/firefliesmcp/) [Connect to Fireflies MCP. Search meeting transcripts, fetch recordings, manage channels, create soundbites, and retrieve analytics from your AI workflows.](/agentkit/connectors/firefliesmcp/) [Vendor MCP20 tools](/agentkit/connectors/firefliesmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fiscalai.svg)](/agentkit/connectors/fiscalaimcp/) [FiscalAI MCPOAuth 2.1/DCR](/agentkit/connectors/fiscalaimcp/) [Connect to FiscalAI MCP. Access financial data for public companies including SEC filings, earnings, stock prices, financial ratios, and company profiles.](/agentkit/connectors/fiscalaimcp/) [Vendor MCP2 tools](/agentkit/connectors/fiscalaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/flux.svg)](/agentkit/connectors/fluxmcp/) [Flux MCPOAuth 2.1/DCR](/agentkit/connectors/fluxmcp/) [Flux by Black Forest Labs provides state-of-the-art AI image generation via the FLUX.1 family of models. Generate high-quality images from text prompts...](/agentkit/connectors/fluxmcp/) [Vendor MCP10 tools](/agentkit/connectors/fluxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/folk.svg)](/agentkit/connectors/folkmcp/) [Folk MCPOAuth 2.1/DCR](/agentkit/connectors/folkmcp/) [Folk is a collaborative CRM that helps teams manage contacts, track relationships, and run outreach — all in one workspace.](/agentkit/connectors/folkmcp/) [Vendor MCP14 tools](/agentkit/connectors/folkmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/freshdesk.png)](/agentkit/connectors/freshdesk/) [FreshdeskBasic Auth](/agentkit/connectors/freshdesk/) [Connect to Freshdesk. Manage tickets, contacts, companies, and customer support workflows](/agentkit/connectors/freshdesk/) [scalekit34 tools](/agentkit/connectors/freshdesk/) [![](https://app.frontapp.com/v2/favicon192.external-BvfUPbjy.png)](/agentkit/connectors/front/) [FrontOAuth 2.0](/agentkit/connectors/front/) [Connect to Front to manage conversations, messages, comments, drafts, contacts, tags, inboxes, teammates, and channels.](/agentkit/connectors/front/) [scalekit55 tools](/agentkit/connectors/front/) [![](https://app.frontapp.com/favicon.ico)](/agentkit/connectors/frontmcp/) [Front MCPOAuth 2.1](/agentkit/connectors/frontmcp/) [Connect to Front via MCP to manage conversations, comments, drafts, contacts, tags, inboxes, and teammates directly from your AI workflows.](/agentkit/connectors/frontmcp/) [Vendor MCP25 tools](/agentkit/connectors/frontmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fullenrich.svg)](/agentkit/connectors/fullenrichmcp/) [Fullenrich MCPOAuth 2.1/DCR](/agentkit/connectors/fullenrichmcp/) [Connect to FullEnrich MCP. Enrich contacts with verified email addresses and phone numbers using waterfall enrichment across multiple data providers.](/agentkit/connectors/fullenrichmcp/) [Vendor MCP13 tools](/agentkit/connectors/fullenrichmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gainsight.svg)](/agentkit/connectors/gainsight/) [GainsightAPI Key](/agentkit/connectors/gainsight/) [Connect to Gainsight Customer Success to manage companies, contacts, calls to action, success plans, timeline activities, and custom objects. Power...](/agentkit/connectors/gainsight/) [scalekit28 tools](/agentkit/connectors/gainsight/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/github/) [GithubOAuth 2.0](/agentkit/connectors/github/) [GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code.](/agentkit/connectors/github/) [scalekit217 tools](/agentkit/connectors/github/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/githubpat/) [GitHub (Personal Access Token)Bearer Token](/agentkit/connectors/githubpat/) [GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code. This variant...](/agentkit/connectors/githubpat/) [scalekit217 tools](/agentkit/connectors/githubpat/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/githubmcp/) [GitHub MCPOAuth 2.1](/agentkit/connectors/githubmcp/) [Connect to GitHub MCP. Manage repositories, issues, pull requests, branches, and files directly from your AI workflows.](/agentkit/connectors/githubmcp/) [Vendor MCP44 tools](/agentkit/connectors/githubmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gitlab.svg)](/agentkit/connectors/gitlab/) [GitLabOAuth 2.0](/agentkit/connectors/gitlab/) [Connect to GitLab to manage repositories, issues, merge requests, pipelines, CI/CD, users, groups, and DevOps workflows.](/agentkit/connectors/gitlab/) [scalekit189 tools](/agentkit/connectors/gitlab/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/globalping.svg)](/agentkit/connectors/globalpingmcp/) [Globalping MCPOAuth 2.1/DCR](/agentkit/connectors/globalpingmcp/) [Globalping is a global network measurement platform for running ping, traceroute, DNS lookup, HTTP, and MTR tests from hundreds of probe locations...](/agentkit/connectors/globalpingmcp/) [Vendor MCP12 tools](/agentkit/connectors/globalpingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gmail.svg)](/agentkit/connectors/gmail/) [GmailOAuth 2.0](/agentkit/connectors/gmail/) [Gmail is Google's cloud based email service that allows you to access your messages from any computer or device with just a web browser.](/agentkit/connectors/gmail/) [scalekit48 tools](/agentkit/connectors/gmail/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gocardless.svg)](/agentkit/connectors/gocardlessmcp/) [GoCardless MCPOAuth 2.1/DCR](/agentkit/connectors/gocardlessmcp/) [Connect to GoCardless MCP. Retrieve and list customers, mandates, payments, payouts, refunds, and subscriptions, and explore integration options from your...](/agentkit/connectors/gocardlessmcp/) [Vendor MCP24 tools](/agentkit/connectors/gocardlessmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gong/) [GongOAuth 2.0](/agentkit/connectors/gong/) [Connect with Gong to sync calls, transcripts, insights, coaching and CRM activity](/agentkit/connectors/gong/) [scalekit49 tools](/agentkit/connectors/gong/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gongmcp/) [Gong MCPOAuth 2.1](/agentkit/connectors/gongmcp/) [Connect with Gong MCP to access calls, transcripts, insights, coaching, and sales engagement data via the Model Context Protocol](/agentkit/connectors/gongmcp/) [Vendor MCP3 tools](/agentkit/connectors/gongmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_ads.png)](/agentkit/connectors/googleads/) [Google AdsOAuth 2.0](/agentkit/connectors/googleads/) [Connect to Google Ads to manage advertising campaigns, analyze performance metrics, and optimize ad spending across Google's advertising platform](/agentkit/connectors/googleads/) [scalekit35 tools](/agentkit/connectors/googleads/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googleanalytics.svg)](/agentkit/connectors/googleanalytics/) [Google AnalyticsOAuth 2.0](/agentkit/connectors/googleanalytics/) [Connect to Google Analytics (GA4) to run reports, realtime reports, and pivot reports, check dimension/metric compatibility, and manage audience exports...](/agentkit/connectors/googleanalytics/) [scalekit66 tools](/agentkit/connectors/googleanalytics/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg)](/agentkit/connectors/bigquery/) [Google BigQueryOAuth 2.0](/agentkit/connectors/bigquery/) [BigQuery is Google Cloud’s fully-managed enterprise data warehouse for analytics at scale.](/agentkit/connectors/bigquery/) [scalekit47 tools](/agentkit/connectors/bigquery/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google.svg)](/agentkit/connectors/googlebusinessprofile/) [Google Business ProfileOAuth 2.0](/agentkit/connectors/googlebusinessprofile/) [Google Business Profile lets businesses manage their presence across Google Search and Maps — business information, locations, performance/insights...](/agentkit/connectors/googlebusinessprofile/) [scalekit56 tools](/agentkit/connectors/googlebusinessprofile/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_calendar.svg)](/agentkit/connectors/googlecalendar/) [Google CalendarOAuth 2.0](/agentkit/connectors/googlecalendar/) [Google Calendar is Google's cloud-based calendar service that allows you to manage your events, appointments, and schedules from any computer or device...](/agentkit/connectors/googlecalendar/) [scalekit30 tools](/agentkit/connectors/googlecalendar/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlechat.svg)](/agentkit/connectors/googlechat/) [Google ChatOAuth 2.0](/agentkit/connectors/googlechat/) [Google Chat is Google's messaging and collaboration platform that lets you create and manage spaces, send and search messages, react with emoji, and...](/agentkit/connectors/googlechat/) [scalekit54 tools](/agentkit/connectors/googlechat/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googleclassroom.svg)](/agentkit/connectors/googleclassroom/) [Google ClassroomOAuth 2.0](/agentkit/connectors/googleclassroom/) [Google Classroom is Google's free web-based platform for schools that streamlines creating, distributing, and grading assignments, and simplifies...](/agentkit/connectors/googleclassroom/) [scalekit76 tools](/agentkit/connectors/googleclassroom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlecloudvision.svg)](/agentkit/connectors/googlecloudvision/) [Google Cloud VisionOAuth 2.0](/agentkit/connectors/googlecloudvision/) [Google Cloud Vision API lets you derive insights from images using pre-trained machine learning models — label detection, OCR/text extraction, face and...](/agentkit/connectors/googlecloudvision/) [scalekit27 tools](/agentkit/connectors/googlecloudvision/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlecontacts.svg)](/agentkit/connectors/googlecontacts/) [Google ContactsOAuth 2.0](/agentkit/connectors/googlecontacts/) [Google Contacts (People API) lets you manage your contacts, contact groups, and directory information. Create, read, update, and delete contacts and...](/agentkit/connectors/googlecontacts/) [scalekit24 tools](/agentkit/connectors/googlecontacts/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_docs.svg)](/agentkit/connectors/googledocs/) [Google DocsOAuth 2.0](/agentkit/connectors/googledocs/) [Connect to Google Docs. Create, edit, and collaborate on documents](/agentkit/connectors/googledocs/) [scalekit47 tools](/agentkit/connectors/googledocs/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_drive.svg)](/agentkit/connectors/googledrive/) [Google DriveOAuth 2.0](/agentkit/connectors/googledrive/) [Connect to Google Drive. Manage files, folders, and sharing permissions](/agentkit/connectors/googledrive/) [scalekit47 tools](/agentkit/connectors/googledrive/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_forms.svg)](/agentkit/connectors/googleforms/) [Google FormsOAuth 2.0](/agentkit/connectors/googleforms/) [Connect to Google Forms. Create, view, and manage forms and responses securely](/agentkit/connectors/googleforms/) [scalekit10 tools](/agentkit/connectors/googleforms/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlelooker.svg)](/agentkit/connectors/googlelooker/) [Google LookerOAuth 2.0](/agentkit/connectors/googlelooker/) [Connect to Google Looker or self-hosted Looker Core. Browse dashboards, run Looks, query LookML models, and access BI data programmatically.](/agentkit/connectors/googlelooker/) [scalekit31 tools](/agentkit/connectors/googlelooker/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_meet.svg)](/agentkit/connectors/googlemeet/) [Google MeetOAuth 2.0](/agentkit/connectors/googlemeet/) [Connect to Google Meet. Create and manage video meetings with powerful collaboration features](/agentkit/connectors/googlemeet/) [scalekit16 tools](/agentkit/connectors/googlemeet/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlephotos.svg)](/agentkit/connectors/googlephotos/) [Google PhotosOAuth 2.0](/agentkit/connectors/googlephotos/) [Google Photos is Google's photo and video storage service for uploading, organizing into albums, and managing media created by your app.](/agentkit/connectors/googlephotos/) [scalekit17 tools](/agentkit/connectors/googlephotos/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlesearch.svg)](/agentkit/connectors/googlesearchconsole/) [Google Search ConsoleOAuth 2.0](/agentkit/connectors/googlesearchconsole/) [Google Search Console (the Search Console API, formerly Webmaster Tools API) lets you monitor and manage a site's presence in Google Search results —...](/agentkit/connectors/googlesearchconsole/) [scalekit10 tools](/agentkit/connectors/googlesearchconsole/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_sheets.svg)](/agentkit/connectors/googlesheets/) [Google SheetsOAuth 2.0](/agentkit/connectors/googlesheets/) [Connect to Google Sheets. Create, edit, and analyze spreadsheets with powerful data management capabilities](/agentkit/connectors/googlesheets/) [scalekit48 tools](/agentkit/connectors/googlesheets/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_slides.svg)](/agentkit/connectors/googleslides/) [Google SlidesOAuth 2.0](/agentkit/connectors/googleslides/) [Connect to Google Slides to create, read, and modify presentations programmatically.](/agentkit/connectors/googleslides/) [scalekit5 tools](/agentkit/connectors/googleslides/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googletasks.svg)](/agentkit/connectors/googletasks/) [Google TasksOAuth 2.0](/agentkit/connectors/googletasks/) [Google Tasks is Google's task management service for creating and organizing to-do items and task lists, synced across Gmail, Calendar, and mobile devices.](/agentkit/connectors/googletasks/) [scalekit12 tools](/agentkit/connectors/googletasks/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google.svg)](/agentkit/connectors/googledwd/) [Google Workspace (DWD)Service Account (DWD)](/agentkit/connectors/googledwd/) [Connect to Google Workspace APIs (Gmail, Drive, Docs, Sheets, Slides, Forms) using a GCP service account with Domain-Wide Delegation for server-to-server...](/agentkit/connectors/googledwd/) [scalekit100 tools](/agentkit/connectors/googledwd/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gorgias.svg)](/agentkit/connectors/gorgiasmcp/) [Gorgias MCPOAuth 2.1/DCR](/agentkit/connectors/gorgiasmcp/) [Customer support helpdesk for e-commerce brands. Centralizes conversations from email, chat, social media, and SMS with ticket management and automation.](/agentkit/connectors/gorgiasmcp/) [Vendor MCP82 tools](/agentkit/connectors/gorgiasmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grain/) [GrainBearer Token](/agentkit/connectors/grain/) [Grain's REST API for managing meeting recordings, transcripts, webhooks, and workspace data. Search and retrieve recordings and transcripts, upload and...](/agentkit/connectors/grain/) [scalekit19 tools](/agentkit/connectors/grain/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grainmcp/) [Grain MCPOAuth 2.1/DCR](/agentkit/connectors/grainmcp/) [Grain is a meeting recording and intelligence platform. Use this connector to search and retrieve meeting recordings, transcripts, notes, action items...](/agentkit/connectors/grainmcp/) [Vendor MCP41 tools](/agentkit/connectors/grainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granola/) [GranolaBearer Token](/agentkit/connectors/granola/) [Connect to Granola to access AI-generated meeting notes, summaries, transcripts, and attendee data from your workspace. Granola automatically records and...](/agentkit/connectors/granola/) [scalekit9 tools](/agentkit/connectors/granola/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granolamcp/) [Granola MCPOAuth 2.1/DCR](/agentkit/connectors/granolamcp/) [Connect to Granola MCP using OAuth 2.1 with MCP discovery and dynamic client registration.](/agentkit/connectors/granolamcp/) [Vendor MCP6 tools](/agentkit/connectors/granolamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/greptile.svg)](/agentkit/connectors/greptilmcp/) [Greptile MCPOAuth 2.1/DCR](/agentkit/connectors/greptilmcp/) [AI-powered code search and understanding API that indexes GitHub and GitLab repositories, enabling natural language queries over codebases.](/agentkit/connectors/greptilmcp/) [Vendor MCP16 tools](/agentkit/connectors/greptilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gtmetrix.svg)](/agentkit/connectors/gtmetrixmcp/) [GTmetrix MCPOAuth 2.1/DCR](/agentkit/connectors/gtmetrixmcp/) [Connect to GTmetrix MCP to analyze web page performance, run speed tests, monitor Core Web Vitals, and get actionable optimization recommendations...](/agentkit/connectors/gtmetrixmcp/) [Vendor MCP10 tools](/agentkit/connectors/gtmetrixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gusto.svg)](/agentkit/connectors/gustomcp/) [Gusto MCPOAuth 2.1/DCR](/agentkit/connectors/gustomcp/) [Connect to Gusto MCP. Manage employees, contractors, payroll, departments, and company data from your AI workflows.](/agentkit/connectors/gustomcp/) [Vendor MCP50 tools](/agentkit/connectors/gustomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/happyscribe.svg)](/agentkit/connectors/happyscribemcp/) [HappyScribe MCPOAuth 2.1/DCR](/agentkit/connectors/happyscribemcp/) [HappyScribe is an AI-powered transcription and translation service. Connect your HappyScribe account to search transcripts, generate meeting summaries...](/agentkit/connectors/happyscribemcp/) [Vendor MCP39 tools](/agentkit/connectors/happyscribemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/harvestapp.svg)](/agentkit/connectors/harvestmcp/) [Harvest MCPOAuth 2.1/DCR](/agentkit/connectors/harvestmcp/) [Harvest is a time tracking and invoicing tool that helps teams track time, manage projects, and create invoices.](/agentkit/connectors/harvestmcp/) [Vendor MCP36 tools](/agentkit/connectors/harvestmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/harvestapi.svg)](/agentkit/connectors/harvestapi/) [HarvestAPIAPI Key](/agentkit/connectors/harvestapi/) [Connect to HarvestAPI to scrape LinkedIn profiles, companies, and job listings, and search for people and jobs using LinkedIn data. Enables AI agents to...](/agentkit/connectors/harvestapi/) [scalekit25 tools](/agentkit/connectors/harvestapi/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hex.svg)](/agentkit/connectors/hexmcp/) [Hex MCPOAuth 2.1/DCR](/agentkit/connectors/hexmcp/) [Connect to Hex MCP. Create and continue data analysis threads, search projects, and query your data using natural language from your AI workflows.](/agentkit/connectors/hexmcp/) [Vendor MCP5 tools](/agentkit/connectors/hexmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/heyreach.svg)](/agentkit/connectors/heyreach/) [HeyReachAPI Key](/agentkit/connectors/heyreach/) [Connect to HeyReach to manage LinkedIn outreach campaigns, lead lists, and conversations. List campaigns, retrieve leads, monitor campaign progress, and...](/agentkit/connectors/heyreach/) [scalekit14 tools](/agentkit/connectors/heyreach/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/higgsfield.svg)](/agentkit/connectors/higgsfieldmcp/) [Higgsfield MCPOAuth 2.1/DCR](/agentkit/connectors/higgsfieldmcp/) [Connect to Higgsfield MCP to generate AI images and videos, train consistent characters, and manage your creation history across 30+ models including...](/agentkit/connectors/higgsfieldmcp/) [Vendor MCP82 tools](/agentkit/connectors/higgsfieldmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hub_spot.svg)](/agentkit/connectors/hubspot/) [HubSpotOAuth 2.0](/agentkit/connectors/hubspot/) [Connect to HubSpot CRM. Manage contacts, deals, companies, and marketing automation](/agentkit/connectors/hubspot/) [scalekit457 tools](/agentkit/connectors/hubspot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hub_spot.svg)](/agentkit/connectors/hubspotmcp/) [HubSpot MCPOAuth 2.1](/agentkit/connectors/hubspotmcp/) [Connect to HubSpot MCP. Manage CRM contacts, companies, deals, landing pages, campaigns, and analytics from your AI workflows.](/agentkit/connectors/hubspotmcp/) [Vendor MCP22 tools](/agentkit/connectors/hubspotmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/huggingface.svg)](/agentkit/connectors/huggingfacemcp/) [Hugging face MCPOAuth 2.1/DCR](/agentkit/connectors/huggingfacemcp/) [Connect to Hugging Face MCP. Search and manage models, datasets, spaces, and collections on the Hugging Face Hub.](/agentkit/connectors/huggingfacemcp/) [Vendor MCP11 tools](/agentkit/connectors/huggingfacemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/icepanel.png)](/agentkit/connectors/icepanelmcp/) [IcePanel MCPOAuth 2.1/DCR](/agentkit/connectors/icepanelmcp/) [Connect your IcePanel software architecture models to AI agents. Query and update your C4 model landscapes — systems, apps, components, connections, and...](/agentkit/connectors/icepanelmcp/) [Vendor MCP24 tools](/agentkit/connectors/icepanelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/igpt.svg)](/agentkit/connectors/igptmcp/) [IGPT MCPOAuth 2.1/DCR](/agentkit/connectors/igptmcp/) [IGPT is an AI assistant platform that exposes its capabilities via an MCP server, enabling agents to interact with AI-powered tools and workflows.](/agentkit/connectors/igptmcp/) [Vendor MCP2 tools](/agentkit/connectors/igptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/intercom.svg)](/agentkit/connectors/intercom/) [IntercomOAuth 2.0](/agentkit/connectors/intercom/) [Connect to Intercom. Send messages, manage conversations, and interact with users and contacts.](/agentkit/connectors/intercom/) [scalekit113 tools](/agentkit/connectors/intercom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jam.svg)](/agentkit/connectors/jammcp/) [Jam MCPOAuth 2.1/DCR](/agentkit/connectors/jammcp/) [Connect to Jam MCP. Access bug reports, console logs, network requests, user events, and video transcripts from your AI workflows.](/agentkit/connectors/jammcp/) [Vendor MCP15 tools](/agentkit/connectors/jammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jentic.svg)](/agentkit/connectors/jenticmcp/) [Jentic MCPOAuth 2.1/DCR](/agentkit/connectors/jenticmcp/) [Connect to Jentic MCP. Search available API actions, load execution details, manage credentials, and execute API operations from your AI workflows.](/agentkit/connectors/jenticmcp/) [Vendor MCP4 tools](/agentkit/connectors/jenticmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jiminny.svg)](/agentkit/connectors/jiminny/) [JiminnyBearer Token](/agentkit/connectors/jiminny/) [Connect with Jiminny to access call recordings, transcripts, coaching insights, and conversation intelligence data.](/agentkit/connectors/jiminny/) [scalekit27 tools](/agentkit/connectors/jiminny/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jira.svg)](/agentkit/connectors/jira/) [JiraOAuth 2.0](/agentkit/connectors/jira/) [Connect to Jira. Manage issues, projects, workflows, and agile development processes](/agentkit/connectors/jira/) [scalekit374 tools](/agentkit/connectors/jira/) [![](https://wac-cdn.atlassian.com/dam/jcr:be09430e-3f78-4712-a953-ddcbe01ea541/jsd-icon.svg?cdnVersion=3478)](/agentkit/connectors/jiraservicemanagement/) [Jira Service ManagementOAuth 2.0](/agentkit/connectors/jiraservicemanagement/) [Connect to Jira Service Management. Manage customer requests, service desks, organizations, knowledge base articles, SLAs, and queues](/agentkit/connectors/jiraservicemanagement/) [scalekit72 tools](/agentkit/connectors/jiraservicemanagement/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jotform.svg)](/agentkit/connectors/jotformmcp/) [Jotform MCPOAuth 2.1/DCR](/agentkit/connectors/jotformmcp/) [Connect to Jotform MCP. Create and edit forms, retrieve submissions, assign forms, and search assets from your AI workflows.](/agentkit/connectors/jotformmcp/) [Vendor MCP7 tools](/agentkit/connectors/jotformmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kit.svg)](/agentkit/connectors/kitmcp/) [Kit MCPOAuth 2.1/DCR](/agentkit/connectors/kitmcp/) [Connect to Kit MCP. Manage email subscribers, sequences, broadcasts, tags, and forms for your email marketing workflows.](/agentkit/connectors/kitmcp/) [Vendor MCP81 tools](/agentkit/connectors/kitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/klaviyo.svg)](/agentkit/connectors/klaviyomcp/) [Klaviyo MCPOAuth 2.1/DCR](/agentkit/connectors/klaviyomcp/) [Connect to Klaviyo MCP. Report, strategize & create with real-time Klaviyo data](/agentkit/connectors/klaviyomcp/) [Vendor MCP263 tools](/agentkit/connectors/klaviyomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kling.svg)](/agentkit/connectors/klingmcp/) [Kling AI MCPOAuth 2.1/DCR](/agentkit/connectors/klingmcp/) [Kling AI is a video and image generation platform. This MCP connector exposes Kling AI capabilities — including video generation and image generation —...](/agentkit/connectors/klingmcp/) [Vendor MCP10 tools](/agentkit/connectors/klingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/latch.svg)](/agentkit/connectors/latchbiomcp/) [Latch Bio MCPOAuth 2.1/DCR](/agentkit/connectors/latchbiomcp/) [Latch Bio is a cloud bioinformatics platform for running computational biology workflows. Its MCP server lets AI agents list and retrieve files, manage...](/agentkit/connectors/latchbiomcp/) [Vendor MCP9 tools](/agentkit/connectors/latchbiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/launchdarkly.svg)](/agentkit/connectors/launchdarklymcp/) [LaunchDarkly MCPOAuth 2.1/DCR](/agentkit/connectors/launchdarklymcp/) [Connect to LaunchDarkly's hosted MCP server to manage feature flags, experiments, and release controls directly from your AI workflows.](/agentkit/connectors/launchdarklymcp/) [Vendor MCP136 tools](/agentkit/connectors/launchdarklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadboxer.svg)](/agentkit/connectors/leadboxermcp/) [LeadBoxer MCPOAuth 2.1/DCR](/agentkit/connectors/leadboxermcp/) [Connect to LeadBoxer MCP to identify anonymous website visitors and enrich them with firmographic data. LeadBoxer is a B2B lead generation and website...](/agentkit/connectors/leadboxermcp/) [Vendor MCP5 tools](/agentkit/connectors/leadboxermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadfeeder.svg)](/agentkit/connectors/leadfeedermcp/) [Leadfeeder MCPOAuth 2.1/DCR](/agentkit/connectors/leadfeedermcp/) [Connect to Leadfeeder's MCP server to identify website visitors, track B2B leads, and surface company-level intent data directly from your AI workflows.](/agentkit/connectors/leadfeedermcp/) [Vendor MCP58 tools](/agentkit/connectors/leadfeedermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadiq.svg)](/agentkit/connectors/leadiq/) [LeadIQAPI Key](/agentkit/connectors/leadiq/) [Connect to LeadIQ to search and enrich B2B contacts and companies with verified emails, direct dials, and mobile numbers. Build prospect lists and power...](/agentkit/connectors/leadiq/) [scalekit14 tools](/agentkit/connectors/leadiq/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadiq.svg)](/agentkit/connectors/leadiqmcp/) [LeadIQ MCPOAuth 2.1/DCR](/agentkit/connectors/leadiqmcp/) [Connect to LeadIQ via MCP to search and enrich B2B contacts and companies. Access real-time prospect data, company intelligence, and email/phone...](/agentkit/connectors/leadiqmcp/) [Vendor MCP16 tools](/agentkit/connectors/leadiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/legaldatahunter.svg)](/agentkit/connectors/legaldatahuntermcp/) [Legal Data Hunter MCPOAuth 2.1/DCR](/agentkit/connectors/legaldatahuntermcp/) [Connect to Legal Data Hunter MCP. Search and explore indexed legal data sources worldwide, tracking case law, courts, dockets, and legal data coverage...](/agentkit/connectors/legaldatahuntermcp/) [Vendor MCP7 tools](/agentkit/connectors/legaldatahuntermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lemlist.svg)](/agentkit/connectors/lemlistmcp/) [Lemlist MCPOAuth 2.1/DCR](/agentkit/connectors/lemlistmcp/) [Connect to Lemlist MCP. Manage outbound sales campaigns, leads, email sequences, and LinkedIn outreach from your AI workflows.](/agentkit/connectors/lemlistmcp/) [Vendor MCP123 tools](/agentkit/connectors/lemlistmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lilt.svg)](/agentkit/connectors/liltmcp/) [LILT MCPOAuth 2.1/DCR](/agentkit/connectors/liltmcp/) [LILT is an enterprise translation platform that combines AI speed with human expertise to deliver accurate, domain-specific translations at scale. This...](/agentkit/connectors/liltmcp/) [Vendor MCP9 tools](/agentkit/connectors/liltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linear.svg)](/agentkit/connectors/linear/) [LinearOAuth 2.0](/agentkit/connectors/linear/) [Connect to Linear. Manage issues, projects, sprints, and development workflows](/agentkit/connectors/linear/) [scalekit62 tools](/agentkit/connectors/linear/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linear.svg)](/agentkit/connectors/linearmcp/) [Linear MCPOAuth 2.1/DCR](/agentkit/connectors/linearmcp/) [Connect to Linear's hosted MCP server to manage issues, projects, cycles, and comments directly from your AI workflows.](/agentkit/connectors/linearmcp/) [Vendor MCP63 tools](/agentkit/connectors/linearmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkedin.svg)](/agentkit/connectors/linkedin/) [LinkedInOAuth 2.0](/agentkit/connectors/linkedin/) [Connect to LinkedIn to manage posts, ads, organizations, analytics, and professional profiles from your AI workflows.](/agentkit/connectors/linkedin/) [scalekit59 tools](/agentkit/connectors/linkedin/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkly.png)](/agentkit/connectors/linklymcp/) [LinklyHQ MCPOAuth 2.1/PKCE](/agentkit/connectors/linklymcp/) [LinklyHQ is a URL shortening and link management platform offering click analytics, custom domains, UTM tracking, QR codes, and webhook integrations for...](/agentkit/connectors/linklymcp/) [Vendor MCP25 tools](/agentkit/connectors/linklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/listenlabs.svg)](/agentkit/connectors/listenlabsmcp/) [ListenLabs MCPOAuth 2.1/DCR](/agentkit/connectors/listenlabsmcp/) [Listen Labs is a qualitative research platform for creating, launching, and analyzing studies with AI assistance. This MCP connector gives AI agents...](/agentkit/connectors/listenlabsmcp/) [Vendor MCP13 tools](/agentkit/connectors/listenlabsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/logrocket.svg)](/agentkit/connectors/logrocketmcp/) [LogRocket MCPOAuth 2.1/DCR](/agentkit/connectors/logrocketmcp/) [Connect to LogRocket to access session data, query analytics, investigate user-reported issues, and detect regressions directly from your AI workflows.](/agentkit/connectors/logrocketmcp/) [Vendor MCP8 tools](/agentkit/connectors/logrocketmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lokalise.svg)](/agentkit/connectors/lokalise/) [LokaliseAPI Key](/agentkit/connectors/lokalise/) [Connect to Lokalise to manage software and content localization: projects, translation keys, translations, languages, comments, contributors, glossary...](/agentkit/connectors/lokalise/) [scalekit109 tools](/agentkit/connectors/lokalise/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/loops.svg)](/agentkit/connectors/loopsmcp/) [Loops MCPOAuth 2.1/DCR](/agentkit/connectors/loopsmcp/) [Connect to Loops MCP. Create and manage loops and tasks, set priorities, track work queue stats, and ship completed loops from your AI workflows.](/agentkit/connectors/loopsmcp/) [Vendor MCP20 tools](/agentkit/connectors/loopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lucid.svg)](/agentkit/connectors/lucidmcp/) [Lucid MCPOAuth 2.1/DCR](/agentkit/connectors/lucidmcp/) [Connect to Lucid. Create and edit Lucidchart diagrams, Lucidspark boards, and Lucidscale visualizations from your AI workflows.](/agentkit/connectors/lucidmcp/) [Vendor MCP35 tools](/agentkit/connectors/lucidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lunarcrush.svg)](/agentkit/connectors/lunarcrushmcp/) [Lunarcrush MCPOAuth 2.1/DCR](/agentkit/connectors/lunarcrushmcp/) [Connect to LunarCrush MCP. Access social intelligence, sentiment analytics, and market data for crypto assets from your AI workflows.](/agentkit/connectors/lunarcrushmcp/) [Vendor MCP15 tools](/agentkit/connectors/lunarcrushmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lusha.svg)](/agentkit/connectors/lushamcp/) [Lusha MCPAPI Key](/agentkit/connectors/lushamcp/) [Connect to Lusha MCP. Search and enrich B2B contacts and companies, find lookalikes, run prospecting searches, and access intent and activity signals from...](/agentkit/connectors/lushamcp/) [Vendor MCP37 tools](/agentkit/connectors/lushamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/magicpatterns.svg)](/agentkit/connectors/magicpatternsmcp/) [Magic Patterns MCPOAuth 2.1/DCR](/agentkit/connectors/magicpatternsmcp/) [Connect to Magic Patterns, the AI-powered UI design tool. Generate, edit, and manage design components and artifacts from your AI workflows.](/agentkit/connectors/magicpatternsmcp/) [Vendor MCP23 tools](/agentkit/connectors/magicpatternsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailchimp.svg)](/agentkit/connectors/mailchimp/) [MailchimpOAuth 2.0](/agentkit/connectors/mailchimp/) [Connect to Mailchimp to manage audiences, campaigns, templates, automations, and reports.](/agentkit/connectors/mailchimp/) [scalekit73 tools](/agentkit/connectors/mailchimp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailercloud.svg)](/agentkit/connectors/mailercloudmcp/) [Mailercloud MCPOAuth 2.1/DCR](/agentkit/connectors/mailercloudmcp/) [Connect to Mailer Cloud MCP. Manage email campaigns, subscriber lists, and automation workflows for your email marketing operations.](/agentkit/connectors/mailercloudmcp/) [Vendor MCP47 tools](/agentkit/connectors/mailercloudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailerlite.svg)](/agentkit/connectors/mailerlitemcp/) [Mailerlite MCPOAuth 2.1/DCR](/agentkit/connectors/mailerlitemcp/) [Connect to MailerLite MCP. Manage email campaigns, subscribers, groups, automations, and forms from your AI workflows.](/agentkit/connectors/mailerlitemcp/) [Vendor MCP77 tools](/agentkit/connectors/mailerlitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailgun.svg)](/agentkit/connectors/mailgun/) [MailgunAPI Key](/agentkit/connectors/mailgun/) [Connect to Mailgun to send transactional and marketing email, manage domains and DNS/DKIM security, mailing lists, suppressions (bounces, complaints...](/agentkit/connectors/mailgun/) [scalekit259 tools](/agentkit/connectors/mailgun/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailtrap.svg)](/agentkit/connectors/mailtrap/) [MailtrapBearer Token](/agentkit/connectors/mailtrap/) [Mailtrap is an email delivery platform for developers that provides transactional and bulk email sending, email sandbox testing, and deliverability tools....](/agentkit/connectors/mailtrap/) [scalekit92 tools](/agentkit/connectors/mailtrap/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/make.svg)](/agentkit/connectors/makemcp/) [Make MCPOAuth 2.1/DCR](/agentkit/connectors/makemcp/) [Connect to Make (formerly Integromat). Build, run, and manage automation scenarios, data stores, webhooks, and connections across thousands of apps from...](/agentkit/connectors/makemcp/) [Vendor MCP163 tools](/agentkit/connectors/makemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mem.svg)](/agentkit/connectors/memmcp/) [Mem MCPOAuth 2.1/DCR](/agentkit/connectors/memmcp/) [A hosted MCP server that gives AI tools secure access to your Mem notes and collections — enabling AI agents to read, create, search, and organize notes...](/agentkit/connectors/memmcp/) [Vendor MCP23 tools](/agentkit/connectors/memmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mem0.svg)](/agentkit/connectors/mem0mcp/) [Mem0 MCPOAuth 2.1/DCR](/agentkit/connectors/mem0mcp/) [Connect to Mem0 MCP. Store, search, and retrieve persistent memory for AI agents and applications using semantic search.](/agentkit/connectors/mem0mcp/) [Vendor MCP11 tools](/agentkit/connectors/mem0mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/memberstack.svg)](/agentkit/connectors/memberstackmcp/) [Memberstack MCPOAuth 2.1/DCR](/agentkit/connectors/memberstackmcp/) [Connect to Memberstack MCP. Manage members, plans, form submissions, and permissions for your membership-based application.](/agentkit/connectors/memberstackmcp/) [Vendor MCP69 tools](/agentkit/connectors/memberstackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mercury.svg)](/agentkit/connectors/mercurymcp/) [Mercury MCPOAuth 2.1/DCR](/agentkit/connectors/mercurymcp/) [Connect to Mercury. Access accounts, transactions, recipients, invoices, treasury, webhooks, and approval requests for startup banking workflows.](/agentkit/connectors/mercurymcp/) [Vendor MCP35 tools](/agentkit/connectors/mercurymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metaview.svg)](/agentkit/connectors/metaviewmcp/) [Metaview MCPOAuth 2.1/DCR](/agentkit/connectors/metaviewmcp/) [Metaview is an agentic recruiting platform that automates end-to-end hiring workflows — from candidate sourcing and outreach to interview note-taking and...](/agentkit/connectors/metaviewmcp/) [Vendor MCP46 tools](/agentkit/connectors/metaviewmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metricool.svg)](/agentkit/connectors/metricoolmcp/) [Metricool MCPOAuth 2.1/DCR](/agentkit/connectors/metricoolmcp/) [Metricool is a social media analytics and scheduling platform for managing, analyzing, and scheduling content across Instagram, Twitter/X, Facebook...](/agentkit/connectors/metricoolmcp/) [Vendor MCP9 tools](/agentkit/connectors/metricoolmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/excel.svg)](/agentkit/connectors/microsoftexcel/) [Microsoft ExcelOAuth 2.0](/agentkit/connectors/microsoftexcel/) [Connect to Microsoft Excel. Access, read, and modify spreadsheets stored in OneDrive or SharePoint through Microsoft Graph API.](/agentkit/connectors/microsoftexcel/) [scalekit47 tools](/agentkit/connectors/microsoftexcel/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/word.svg)](/agentkit/connectors/microsoftword/) [Microsoft WordOAuth 2.0](/agentkit/connectors/microsoftword/) [Connect to Microsoft Word. Authenticate with your Microsoft account to create, read, and edit Word documents stored in OneDrive or SharePoint through...](/agentkit/connectors/microsoftword/) [scalekit10 tools](/agentkit/connectors/microsoftword/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/minicoursegenerator.svg)](/agentkit/connectors/minicoursegeneratormcp/) [Mini Course Generator MCPOAuth 2.1/DCR](/agentkit/connectors/minicoursegeneratormcp/) [Mini Course Generator is a platform for creating and publishing short, focused online mini-courses. It enables creators to build bite-sized educational...](/agentkit/connectors/minicoursegeneratormcp/) [Vendor MCP44 tools](/agentkit/connectors/minicoursegeneratormcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mintlify.svg)](/agentkit/connectors/mintlifymcp/) [Mintlify MCPOAuth 2.1/DCR](/agentkit/connectors/mintlifymcp/) [Connect to Mintlify MCP. Read and edit documentation pages, manage navigation nodes, search content, and publish changes via pull requests from your AI...](/agentkit/connectors/mintlifymcp/) [Vendor MCP19 tools](/agentkit/connectors/mintlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miro/) [MiroOAuth 2.0](/agentkit/connectors/miro/) [Miro is a visual collaboration platform for teams. Manage boards, sticky notes, shapes, cards, frames, connectors, images, and tags using the Miro REST...](/agentkit/connectors/miro/) [scalekit115 tools](/agentkit/connectors/miro/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miromcp/) [Miro MCPOAuth 2.1/DCR](/agentkit/connectors/miromcp/) [Connect to Miro MCP to create and manage boards, frames, sticky notes, shapes, diagrams, and comments directly from your AI workflows.](/agentkit/connectors/miromcp/) [Vendor MCP65 tools](/agentkit/connectors/miromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixmax.svg)](/agentkit/connectors/mixmaxmcp/) [Mixmax MCPOAuth 2.1/DCR](/agentkit/connectors/mixmaxmcp/) [Connect to Mixmax MCP. Manage email sequences, templates, contacts, and engagement analytics from your AI workflows.](/agentkit/connectors/mixmaxmcp/) [Vendor MCP3 tools](/agentkit/connectors/mixmaxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixpanel.svg)](/agentkit/connectors/mixpanelanalytics/) [Mixpanel AnalyticsService Account](/agentkit/connectors/mixpanelanalytics/) [Connect to Mixpanel's Query API, Lexicon Schemas, and Warehouse Connectors to run segmentation, funnel, retention, and Insights reports, execute custom...](/agentkit/connectors/mixpanelanalytics/) [scalekit51 tools](/agentkit/connectors/mixpanelanalytics/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixpanel.svg)](/agentkit/connectors/mixpanelcompliance/) [Mixpanel ComplianceBearer Token](/agentkit/connectors/mixpanelcompliance/) [Connect to Mixpanel's GDPR/CCPA compliance API to submit and track end-user data deletion (right to erasure) and data retrieval (subject access) requests....](/agentkit/connectors/mixpanelcompliance/) [scalekit5 tools](/agentkit/connectors/mixpanelcompliance/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixpanel.svg)](/agentkit/connectors/mixpanelingestion/) [Mixpanel IngestionService Account](/agentkit/connectors/mixpanelingestion/) [Connect to Mixpanel's Ingestion API to track events, manage user and group profiles, resolve identities, replace lookup tables, and evaluate feature...](/agentkit/connectors/mixpanelingestion/) [scalekit25 tools](/agentkit/connectors/mixpanelingestion/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mobbins.svg)](/agentkit/connectors/mobbinmcp/) [Mobbin MCPOAuth 2.1/DCR](/agentkit/connectors/mobbinmcp/) [Connect to Mobbin's MCP server to search real-world UI and UX design references from mobile apps, web apps, and websites using natural language. Returns...](/agentkit/connectors/mobbinmcp/) [Vendor MCP3 tools](/agentkit/connectors/mobbinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/momentum..svg)](/agentkit/connectors/momentum/) [MomentumAPI Key](/agentkit/connectors/momentum/) [Connect to Momentum, the AI-powered revenue intelligence platform. Retrieve meetings with attendee and transcript details, ingest and remap meetings, run...](/agentkit/connectors/momentum/) [scalekit8 tools](/agentkit/connectors/momentum/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/mondaymcp/) [Monday MCPOAuth 2.1/DCR](/agentkit/connectors/mondaymcp/) [Connect to the monday.com MCP server to manage boards, items, columns, docs, and workflows directly from your AI agents.](/agentkit/connectors/mondaymcp/) [Vendor MCP94 tools](/agentkit/connectors/mondaymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/monday/) [Monday.comOAuth 2.0](/agentkit/connectors/monday/) [Connect to Monday.com. Manage boards, tasks, workflows, teams, and project collaboration](/agentkit/connectors/monday/) [scalekit73 tools](/agentkit/connectors/monday/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motherduck.svg)](/agentkit/connectors/motherduckmcp/) [MotherDuck MCPOAuth 2.1/DCR](/agentkit/connectors/motherduckmcp/) [Connect to MotherDuck MCP. Query and analyze DuckDB databases, explore schemas, create visualizations, and automate data workflows from your AI workflows.](/agentkit/connectors/motherduckmcp/) [Vendor MCP44 tools](/agentkit/connectors/motherduckmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motion.svg)](/agentkit/connectors/motionmcp/) [Motion MCPOAuth 2.1/DCR](/agentkit/connectors/motionmcp/) [Connect to Motion MCP. Manage tasks, projects, workspaces, and schedules in the Motion AI-powered project management platform.](/agentkit/connectors/motionmcp/) [Vendor MCP14 tools](/agentkit/connectors/motionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mtnewswires.svg)](/agentkit/connectors/mtnewswiresmcp/) [MT Newswires MCPOAuth 2.1/DCR](/agentkit/connectors/mtnewswiresmcp/) [Connect to the MT Newswires MCP server on viaNexus to search and retrieve real-time, low-latency financial news across equities, fixed income...](/agentkit/connectors/mtnewswiresmcp/) [Vendor MCP6 tools](/agentkit/connectors/mtnewswiresmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mux.svg)](/agentkit/connectors/muxmcp/) [Mux MCPOAuth 2.1/DCR](/agentkit/connectors/muxmcp/) [Mux is a video infrastructure platform for developers, providing APIs for video hosting, on-demand streaming, live streaming, and playback with analytics...](/agentkit/connectors/muxmcp/) [Vendor MCP2 tools](/agentkit/connectors/muxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/neon.svg)](/agentkit/connectors/neonmcp/) [Neon MCPOAuth 2.1/DCR](/agentkit/connectors/neonmcp/) [Connect to Neon MCP. Manage Neon serverless Postgres databases, projects, branches, and queries from your AI workflows.](/agentkit/connectors/neonmcp/) [Vendor MCP35 tools](/agentkit/connectors/neonmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/netlify.svg)](/agentkit/connectors/netlifymcp/) [Netlify MCPOAuth 2.1/DCR](/agentkit/connectors/netlifymcp/) [Build, deploy, and manage Netlify projects — sites, functions, environment variables, forms, blobs, and edge functions — from AI agents via the Netlify...](/agentkit/connectors/netlifymcp/) [Vendor MCP9 tools](/agentkit/connectors/netlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nimble.svg)](/agentkit/connectors/nimblemcp/) [Nimble MCPBearer Token](/agentkit/connectors/nimblemcp/) [Connect to Nimble MCP. Search the web across multiple engines, extract content from any URL, crawl websites at scale, discover all URLs on a site, and run...](/agentkit/connectors/nimblemcp/) [Vendor MCP31 tools](/agentkit/connectors/nimblemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nocodb.svg)](/agentkit/connectors/nocodbmcp/) [NocoDB MCPOAuth 2.1/DCR](/agentkit/connectors/nocodbmcp/) [Connect to NocoDB MCP. Create and manage databases, tables, records, views, and fields from your AI workflows.](/agentkit/connectors/nocodbmcp/) [Vendor MCP11 tools](/agentkit/connectors/nocodbmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notion/) [NotionOAuth 2.0](/agentkit/connectors/notion/) [Connect to Notion workspace. Create, edit pages, manage databases, and collaborate on content](/agentkit/connectors/notion/) [scalekit51 tools](/agentkit/connectors/notion/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notionmcp/) [Notion MCPOAuth 2.1/DCR](/agentkit/connectors/notionmcp/) [Connect to Notion MCP. Create and update pages, databases, comments, and views from your AI workflows.](/agentkit/connectors/notionmcp/) [Vendor MCP28 tools](/agentkit/connectors/notionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/onedrive.svg)](/agentkit/connectors/onedrive/) [OneDriveOAuth 2.0](/agentkit/connectors/onedrive/) [Connect to OneDrive. Manage files, folders, and cloud storage with Microsoft OneDrive](/agentkit/connectors/onedrive/) [scalekit46 tools](/agentkit/connectors/onedrive/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/onenote.svg)](/agentkit/connectors/onenote/) [OneNoteOAuth 2.0](/agentkit/connectors/onenote/) [Connect to Microsoft OneNote. Access, create, and manage notebooks, sections, and pages stored in OneDrive or SharePoint through Microsoft Graph API.](/agentkit/connectors/onenote/) [scalekit13 tools](/agentkit/connectors/onenote/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/onepage.svg)](/agentkit/connectors/onepagemcp/) [Onepage MCPOAuth 2.1/DCR](/agentkit/connectors/onepagemcp/) [Onepage is a website builder platform. The MCP connector lets Claude create, edit, and manage Onepage websites and pages on behalf of the user.](/agentkit/connectors/onepagemcp/) [Vendor MCP54 tools](/agentkit/connectors/onepagemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/openrouter.svg)](/agentkit/connectors/openroutermcp/) [OpenRouter MCPOAuth 2.1/DCR](/agentkit/connectors/openroutermcp/) [Connect to OpenRouter's MCP server to access unified LLM routing, model discovery, and generation tools directly from your AI workflows.](/agentkit/connectors/openroutermcp/) [Vendor MCP23 tools](/agentkit/connectors/openroutermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/otterai.svg)](/agentkit/connectors/otteraimcp/) [OtterAI MCPOAuth 2.1/DCR](/agentkit/connectors/otteraimcp/) [Connect to OtterAI MCP. Search meeting recordings, fetch full transcripts, and retrieve user account info from your AI workflows.](/agentkit/connectors/otteraimcp/) [Vendor MCP3 tools](/agentkit/connectors/otteraimcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/outlook.svg)](/agentkit/connectors/outlook/) [OutlookOAuth 2.0](/agentkit/connectors/outlook/) [Connect to Microsoft Outlook. Manage emails, calendar events, contacts, and tasks](/agentkit/connectors/outlook/) [scalekit126 tools](/agentkit/connectors/outlook/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/outreach.png)](/agentkit/connectors/outreach/) [OutreachOAuth 2.0](/agentkit/connectors/outreach/) [Connect with Outreach to manage prospects, accounts, sequences, emails, calls, and sales engagement workflows.](/agentkit/connectors/outreach/) [scalekit80 tools](/agentkit/connectors/outreach/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pagerduty.svg)](/agentkit/connectors/pagerduty/) [PagerDutyOAuth 2.0](/agentkit/connectors/pagerduty/) [Connect to PagerDuty to manage incidents, services, users, teams, escalation policies, schedules, and on-call rotations.](/agentkit/connectors/pagerduty/) [scalekit71 tools](/agentkit/connectors/pagerduty/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pandadoc.svg)](/agentkit/connectors/pandadocmcp/) [Pandadoc MCPOAuth 2.1/DCR](/agentkit/connectors/pandadocmcp/) [Connect to PandaDoc MCP. Create, send, and manage documents, templates, and e-signatures directly from your AI workflows.](/agentkit/connectors/pandadocmcp/) [Vendor MCP22 tools](/agentkit/connectors/pandadocmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/parallel-ai.svg)](/agentkit/connectors/parallelaitaskmcp/) [Parallel AI Task MCPBearer Token](/agentkit/connectors/parallelaitaskmcp/) [Connect to Parallel AI Task MCP to run deep research tasks and task groups directly from your AI workflows.](/agentkit/connectors/parallelaitaskmcp/) [Vendor MCP4 tools](/agentkit/connectors/parallelaitaskmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pendo.svg)](/agentkit/connectors/pendomcp/) [Pendo MCPOAuth 2.1/DCR](/agentkit/connectors/pendomcp/) [Connect to Pendo MCP to access product analytics, user guidance, and engagement data directly from your AI workflows.](/agentkit/connectors/pendomcp/) [Vendor MCP45 tools](/agentkit/connectors/pendomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/phantombuster.svg)](/agentkit/connectors/phantombuster/) [PhantomBusterAPI Key](/agentkit/connectors/phantombuster/) [Connect to PhantomBuster to automate web scraping and data extraction workflows. Launch, monitor, and manage automation agents that extract data from...](/agentkit/connectors/phantombuster/) [scalekit56 tools](/agentkit/connectors/phantombuster/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/phantombuster.svg)](/agentkit/connectors/phantombustermcp/) [PhantomBuster MCPOAuth 2.1/DCR](/agentkit/connectors/phantombustermcp/) [Connect to PhantomBuster MCP server to launch and manage web automation agents, retrieve scraping outputs, manage leads, and explore workspace resources...](/agentkit/connectors/phantombustermcp/) [Vendor MCP62 tools](/agentkit/connectors/phantombustermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pipedrive.svg)](/agentkit/connectors/pipedrive/) [PipedriveOAuth 2.0](/agentkit/connectors/pipedrive/) [Connect to Pipedrive CRM. Manage deals, contacts, organizations, activities, leads, and notes to streamline your sales pipeline.](/agentkit/connectors/pipedrive/) [scalekit105 tools](/agentkit/connectors/pipedrive/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pipedrive.svg)](/agentkit/connectors/pipedrivemcp/) [Pipedrive MCPOAuth 2.1/DCR](/agentkit/connectors/pipedrivemcp/) [Connect to Pipedrive CRM via MCP to manage deals, contacts, organizations, leads, activities, and notes directly from your AI workflows.](/agentkit/connectors/pipedrivemcp/) [Vendor MCP32 tools](/agentkit/connectors/pipedrivemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pixelbin.svg)](/agentkit/connectors/pixelbinmcp/) [Pixelbin MCPOAuth 2.1/DCR](/agentkit/connectors/pixelbinmcp/) [Image and video transformation, optimization, and management platform.](/agentkit/connectors/pixelbinmcp/) [Vendor MCP7 tools](/agentkit/connectors/pixelbinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plain.svg)](/agentkit/connectors/plainmcp/) [Plain MCPOAuth 2.1/DCR](/agentkit/connectors/plainmcp/) [Connect to Plain MCP. Manage customer support threads, labels, tenants, Help Center articles, and thread field schemas directly from your AI workflows.](/agentkit/connectors/plainmcp/) [Vendor MCP63 tools](/agentkit/connectors/plainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plane.svg)](/agentkit/connectors/planemcp/) [Plane MCPOAuth 2.1/DCR](/agentkit/connectors/planemcp/) [Connect to Plane MCP. Manage projects, work items, cycles, modules, epics, and initiatives in your Plane workspace from AI workflows.](/agentkit/connectors/planemcp/) [Vendor MCP109 tools](/agentkit/connectors/planemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planetscale.svg)](/agentkit/connectors/planetscalemcp/) [Planet Scale MCPOAuth 2.1/DCR](/agentkit/connectors/planetscalemcp/) [Connect to PlanetScale MCP. Run SQL queries, inspect database branches and schemas, get query performance insights, and manage organizations and invoices...](/agentkit/connectors/planetscalemcp/) [Vendor MCP16 tools](/agentkit/connectors/planetscalemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planningcenter.svg)](/agentkit/connectors/planningcentermcp/) [Planning Center MCPOAuth 2.1/DCR](/agentkit/connectors/planningcentermcp/) [Planning Center is a church management platform with modules for people (contact database), giving, check-ins, services planning, groups, registrations...](/agentkit/connectors/planningcentermcp/) [Vendor MCP64 tools](/agentkit/connectors/planningcentermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plaud.svg)](/agentkit/connectors/plaudmcp/) [Plaud MCPOAuth 2.1/DCR](/agentkit/connectors/plaudmcp/) [Connect to Plaud MCP. Browse your Plaud recordings, read AI-generated notes, and pull timestamped transcripts with speaker labels into your AI workflows.](/agentkit/connectors/plaudmcp/) [Vendor MCP5 tools](/agentkit/connectors/plaudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/posthog-1.svg)](/agentkit/connectors/posthogmcp/) [Posthog MCPOAuth 2.1/DCR](/agentkit/connectors/posthogmcp/) [Connect to Posthog MCP to enable your AI agents and tools to directly interact with PostHog's products.](/agentkit/connectors/posthogmcp/) [Vendor MCP200 tools](/agentkit/connectors/posthogmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postman.svg)](/agentkit/connectors/postmanmcp/) [Postman MCPOAuth 2.1/DCR](/agentkit/connectors/postmanmcp/) [Connect to the Postman MCP server to manage collections, workspaces, environments, and APIs directly from your AI workflows.](/agentkit/connectors/postmanmcp/) [Vendor MCP41 tools](/agentkit/connectors/postmanmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postmark.svg)](/agentkit/connectors/postmark/) [PostmarkAPI Key](/agentkit/connectors/postmark/) [Send and track transactional and broadcast email with Postmark. Manage templates, message streams, bounces, suppressions, webhooks, and delivery...](/agentkit/connectors/postmark/) [scalekit59 tools](/agentkit/connectors/postmark/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/prisma.svg)](/agentkit/connectors/prismamcp/) [Prisma MCPOAuth 2.1/DCR](/agentkit/connectors/prismamcp/) [Connect to Prisma MCP. Manage Prisma Postgres databases, run SQL queries, handle backups, and manage connection strings from your AI workflows.](/agentkit/connectors/prismamcp/) [Vendor MCP19 tools](/agentkit/connectors/prismamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/privacy.svg)](/agentkit/connectors/privacymcp/) [Privacy MCPOAuth 2.1/DCR](/agentkit/connectors/privacymcp/) [Connect to Privacy MCP. Create and manage virtual cards, set spend limits, pause or close cards, and review transactions from your AI workflows.](/agentkit/connectors/privacymcp/) [Vendor MCP10 tools](/agentkit/connectors/privacymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/profound.svg)](/agentkit/connectors/profoundmcp/) [Profound MCPOAuth 2.1/DCR](/agentkit/connectors/profoundmcp/) [Profound is an AI search visibility and marketing analytics platform that helps brands understand and optimize their presence across AI-powered answer...](/agentkit/connectors/profoundmcp/) [Vendor MCP15 tools](/agentkit/connectors/profoundmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/prohostai.svg)](/agentkit/connectors/prohostaimcp/) [ProhostAI MCPOAuth 2.1/DCR](/agentkit/connectors/prohostaimcp/) [ProhostAI is an AI-powered property management platform for Airbnb hosts and property managers, offering AI guest messaging, task/cleaning automation...](/agentkit/connectors/prohostaimcp/) [Vendor MCP268 tools](/agentkit/connectors/prohostaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/proshortai.svg)](/agentkit/connectors/proshortai/) [ProShort AIAPI Key](/agentkit/connectors/proshortai/) [Connect to ProShort AI to search and retrieve AI-analyzed sales call recordings, transcripts, and summaries.](/agentkit/connectors/proshortai/) [scalekit5 tools](/agentkit/connectors/proshortai/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pylon.svg)](/agentkit/connectors/pylon/) [PylonBearer Token](/agentkit/connectors/pylon/) [Connect to Pylon, the modern customer support platform, to manage tickets, contacts, accounts, tasks, projects, and knowledge base content.](/agentkit/connectors/pylon/) [scalekit134 tools](/agentkit/connectors/pylon/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pylon.svg)](/agentkit/connectors/pylonmcp/) [Pylon MCPOAuth 2.1/DCR](/agentkit/connectors/pylonmcp/) [Connect to Pylon MCP. Manage customer issues, accounts, projects, milestones, and tasks from your AI workflows.](/agentkit/connectors/pylonmcp/) [Vendor MCP31 tools](/agentkit/connectors/pylonmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Quickbooks.svg)](/agentkit/connectors/quickbooks/) [QuickBooksOAuth 2.0](/agentkit/connectors/quickbooks/) [Connect to QuickBooks Online. Manage customers, vendors, invoices, bills, payments, and financial reports.](/agentkit/connectors/quickbooks/) [scalekit117 tools](/agentkit/connectors/quickbooks/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quicknode.svg)](/agentkit/connectors/quicknodemcp/) [Quicknode MCPOAuth 2.1/DCR](/agentkit/connectors/quicknodemcp/) [Connect to QuickNode MCP. Create and manage blockchain RPC endpoints, configure security rules, set rate limits, and monitor usage and logs from your AI...](/agentkit/connectors/quicknodemcp/) [Vendor MCP19 tools](/agentkit/connectors/quicknodemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quizvideo.svg)](/agentkit/connectors/quizvideomcp/) [Quiz.Video MCPOAuth 2.1/DCR](/agentkit/connectors/quizvideomcp/) [Quiz.Video is an AI-powered platform for creating short-form quiz and flashcard videos. Transform topics, URLs, or documents into shareable quiz and...](/agentkit/connectors/quizvideomcp/) [Vendor MCP30 tools](/agentkit/connectors/quizvideomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quo.svg)](/agentkit/connectors/quomcp/) [Quo MCPOAuth 2.1/DCR](/agentkit/connectors/quomcp/) [Connect to Quo MCP. Access call details, summaries, transcripts, and voicemails, send text messages, and create or update contacts from your AI workflows.](/agentkit/connectors/quomcp/) [Vendor MCP15 tools](/agentkit/connectors/quomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/readai.svg)](/agentkit/connectors/readaimcp/) [Read AI MCPOAuth 2.1/DCR](/agentkit/connectors/readaimcp/) [Connect to Read AI to access your meeting intelligence — transcripts, summaries, action items, and insights from meetings, emails, and chats. Retrieve...](/agentkit/connectors/readaimcp/) [Vendor MCP4 tools](/agentkit/connectors/readaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/recraft.svg)](/agentkit/connectors/recraftmcp/) [Recraft AI MCPOAuth 2.1/DCR](/agentkit/connectors/recraftmcp/) [Connect to Recraft AI MCP. Generate AI-powered images, vectors, icons, and mockups from your AI agents using Recraft's creative design tools.](/agentkit/connectors/recraftmcp/) [Vendor MCP21 tools](/agentkit/connectors/recraftmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/reddit.svg)](/agentkit/connectors/reddit/) [RedditOAuth 2.0](/agentkit/connectors/reddit/) [Connect to Reddit to access user identity, subreddit data, posts, comments, and mod tools.](/agentkit/connectors/reddit/) [scalekit105 tools](/agentkit/connectors/reddit/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/replit.svg)](/agentkit/connectors/replitmcp/) [Replit MCPOAuth 2.1/DCR](/agentkit/connectors/replitmcp/) [Connect to Replit MCP. Create, update, and inspect Replit apps from natural-language prompts, list your apps, and resolve apps by name from your AI...](/agentkit/connectors/replitmcp/) [Vendor MCP8 tools](/agentkit/connectors/replitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resend/) [ResendBearer Token](/agentkit/connectors/resend/) [Resend is an email API platform for developers. Send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts...](/agentkit/connectors/resend/) [scalekit101 tools](/agentkit/connectors/resend/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resendmcp/) [Resend MCPBearer Token](/agentkit/connectors/resendmcp/) [Connect to Resend's official MCP server to send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts, and templates...](/agentkit/connectors/resendmcp/) [Vendor MCP94 tools](/agentkit/connectors/resendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/revealedai.svg)](/agentkit/connectors/revealedaimcp/) [Revealed AI MCPOAuth 2.1/DCR](/agentkit/connectors/revealedaimcp/) [Connect to Revealed AI. Track account signals, buyer personas, and people changes to surface timely outreach actions and account intelligence for B2B...](/agentkit/connectors/revealedaimcp/) [Vendor MCP13 tools](/agentkit/connectors/revealedaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/rize.svg)](/agentkit/connectors/rizemcp/) [Rize MCPOAuth 2.1/DCR](/agentkit/connectors/rizemcp/) [Connect to Rize MCP using OAuth 2.1 with MCP discovery and dynamic client registration. Access and analyze your time tracking data, projects, clients...](/agentkit/connectors/rizemcp/) [Vendor MCP72 tools](/agentkit/connectors/rizemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/roam.svg)](/agentkit/connectors/roammcp/) [Roam MCPOAuth 2.1/DCR](/agentkit/connectors/roammcp/) [Connect to Roam MCP. Access and manage meetings, transcripts, chat messages, calendar events, and people data across your Roam virtual office workspace.](/agentkit/connectors/roammcp/) [Vendor MCP56 tools](/agentkit/connectors/roammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/runware.svg)](/agentkit/connectors/runwaremcp/) [Runware MCPOAuth 2.1/DCR](/agentkit/connectors/runwaremcp/) [Connect to Runware's MCP server to generate and edit images, video, audio, and 3D assets using thousands of AI models through a single API.](/agentkit/connectors/runwaremcp/) [Vendor MCP12 tools](/agentkit/connectors/runwaremcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sales_force.svg)](/agentkit/connectors/salesforce/) [SalesforceOAuth 2.0](/agentkit/connectors/salesforce/) [Connect to Salesforce CRM. Manage leads, opportunities, accounts, and customer relationships](/agentkit/connectors/salesforce/) [scalekit74 tools](/agentkit/connectors/salesforce/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sales_force.svg)](/agentkit/connectors/salesforcemarketingcloud/) [Salesforce Marketing CloudOAuth 2.0 Server-to-Server](/agentkit/connectors/salesforcemarketingcloud/) [Connect to Salesforce Marketing Cloud to manage contacts, data extensions, automations, journeys, and email/SMS/push sends across your marketing programs.](/agentkit/connectors/salesforcemarketingcloud/) [scalekit209 tools](/agentkit/connectors/salesforcemarketingcloud/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/salesloft.svg)](/agentkit/connectors/salesloft/) [SalesloftOAuth 2.0](/agentkit/connectors/salesloft/) [Connect with Salesloft to manage people, cadences, accounts, activities, emails, calls, and notes](/agentkit/connectors/salesloft/) [scalekit56 tools](/agentkit/connectors/salesloft/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sanity.svg)](/agentkit/connectors/sanitymcp/) [Sanity MCPOAuth 2.1/DCR](/agentkit/connectors/sanitymcp/) [Connect to Sanity. Manage structured content, documents, datasets, schemas, releases, and media assets for headless CMS workflows.](/agentkit/connectors/sanitymcp/) [Vendor MCP45 tools](/agentkit/connectors/sanitymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scrapfly.svg)](/agentkit/connectors/scarpflymcp/) [Scarpfly MCPOAuth 2.1/DCR](/agentkit/connectors/scarpflymcp/) [Connect to Scrapfly MCP. Scrape web pages, take screenshots, and control a cloud browser with anti-bot bypass, JS rendering, and proxy support.](/agentkit/connectors/scarpflymcp/) [Vendor MCP31 tools](/agentkit/connectors/scarpflymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scholargateway.svg)](/agentkit/connectors/scholargateway/) [Scholar Gateway MCPOAuth 2.1/DCR](/agentkit/connectors/scholargateway/) [Connect to Scholar Gateway to search Wiley's peer-reviewed academic literature — 8M+ articles from 2,000+ journals spanning sciences, healthcare...](/agentkit/connectors/scholargateway/) [scalekit1 tool](/agentkit/connectors/scholargateway/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scite.svg)](/agentkit/connectors/scitemcp/) [Scite MCPOAuth 2.1/DCR](/agentkit/connectors/scitemcp/) [Connect to Scite's MCP server to search scientific literature, patents, clinical trials, grants, and FDA drug/device safety data, and manage citation...](/agentkit/connectors/scitemcp/) [Vendor MCP25 tools](/agentkit/connectors/scitemcp/) [![](https://seismic.com/favicon.ico)](/agentkit/connectors/seismic/) [SeismicOAuth 2.0](/agentkit/connectors/seismic/) [Connect to Seismic to manage sales enablement content — browse and manage teamsites and library content, work with personal workspace files, search...](/agentkit/connectors/seismic/) [scalekit45 tools](/agentkit/connectors/seismic/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/semaphoreci.svg)](/agentkit/connectors/semaphorecimcp/) [Semaphore CI MCPOAuth 2.1/DCR](/agentkit/connectors/semaphorecimcp/) [Semaphore CI is a fast, cloud-native continuous integration and delivery platform that automates building, testing, and deploying software with flexible...](/agentkit/connectors/semaphorecimcp/) [Vendor MCP18 tools](/agentkit/connectors/semaphorecimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/send.svg)](/agentkit/connectors/sendmcp/) [Send MCPOAuth 2.1/DCR](/agentkit/connectors/sendmcp/) [Connect to Send to create, edit, and share Claude-generated documents as polished web pages with engagement tracking, custom domains, and team asset...](/agentkit/connectors/sendmcp/) [Vendor MCP12 tools](/agentkit/connectors/sendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sendgrid.svg)](/agentkit/connectors/sendgrid/) [SendGridBearer Token](/agentkit/connectors/sendgrid/) [Connect to Twilio SendGrid to send transactional and marketing email at scale, manage templates, contacts, lists, segments, and single sends, verify...](/agentkit/connectors/sendgrid/) [scalekit391 tools](/agentkit/connectors/sendgrid/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sentry.svg)](/agentkit/connectors/sentrymcp/) [Sentry MCPOAuth 2.1/DCR](/agentkit/connectors/sentrymcp/) [Connect to Sentry MCP server to monitor errors, investigate issues, manage projects, and analyze performance directly from your AI workflows.](/agentkit/connectors/sentrymcp/) [Vendor MCP9 tools](/agentkit/connectors/sentrymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/servicenow.svg)](/agentkit/connectors/servicenow/) [ServiceNowOAuth 2.0](/agentkit/connectors/servicenow/) [Connect to ServiceNow. Manage incidents, service requests, CMDB, and IT service management workflows](/agentkit/connectors/servicenow/) [scalekit112 tools](/agentkit/connectors/servicenow/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sharepoint.svg)](/agentkit/connectors/sharepoint/) [SharePointOAuth 2.0](/agentkit/connectors/sharepoint/) [Connect to SharePoint. Manage sites, documents, lists, and collaborative content](/agentkit/connectors/sharepoint/) [scalekit52 tools](/agentkit/connectors/sharepoint/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/signwell.svg)](/agentkit/connectors/signwell/) [SignWellAPI Key](/agentkit/connectors/signwell/) [SignWell is an e-signature platform for sending, signing, and managing documents. Connect to create and send documents for signature, manage templates...](/agentkit/connectors/signwell/) [scalekit26 tools](/agentkit/connectors/signwell/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slack/) [SlackOAuth 2.0](/agentkit/connectors/slack/) [Connect to Slack workspace. Send Messages as Bots or on behalf of users](/agentkit/connectors/slack/) [scalekit91 tools](/agentkit/connectors/slack/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slackmcp/) [Slack MCPOAuth 2.1](/agentkit/connectors/slackmcp/) [Connect to Slack MCP. Send and read messages, search channels and users, manage canvases, and react to messages across your Slack workspace.](/agentkit/connectors/slackmcp/) [Vendor MCP19 tools](/agentkit/connectors/slackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sleekplan.svg)](/agentkit/connectors/sleekplanmcp/) [Sleekplan MCPOAuth 2.1/DCR](/agentkit/connectors/sleekplanmcp/) [Sleekplan is a customer feedback, feature request, and roadmap management platform.](/agentkit/connectors/sleekplanmcp/) [Vendor MCP60 tools](/agentkit/connectors/sleekplanmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slite.svg)](/agentkit/connectors/slitemcp/) [Slite MCPOAuth 2.1/DCR](/agentkit/connectors/slitemcp/) [Connect to Slite MCP. Create and manage notes, channels, collections, and comments in Slite from AI workflows.](/agentkit/connectors/slitemcp/) [Vendor MCP40 tools](/agentkit/connectors/slitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smartling.svg)](/agentkit/connectors/smartlingmcp/) [Smartling MCPOAuth 2.1/DCR](/agentkit/connectors/smartlingmcp/) [Connect to Smartling MCP to manage translation projects, jobs, files, and glossaries, and run machine translation and localization workflows from your AI...](/agentkit/connectors/smartlingmcp/) [Vendor MCP53 tools](/agentkit/connectors/smartlingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smtp2go.svg)](/agentkit/connectors/smtp2go/) [SMTP2GOAPI Key](/agentkit/connectors/smtp2go/) [SMTP2GO is a transactional email and SMS delivery platform for developers. Send transactional and bulk email and SMS, manage templates, sender domains...](/agentkit/connectors/smtp2go/) [scalekit74 tools](/agentkit/connectors/smtp2go/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smtp2go.svg)](/agentkit/connectors/smtp2gomcp/) [SMTP2GO MCPAPI Key](/agentkit/connectors/smtp2gomcp/) [SMTP2GO's MCP server exposes its API documentation and a generic request executor - discover SMTP2GO API endpoints (list-endpoints, get-endpoint...](/agentkit/connectors/smtp2gomcp/) [Vendor MCP5 tools](/agentkit/connectors/smtp2gomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/snowflake.svg)](/agentkit/connectors/snowflake/) [SnowflakeOAuth 2.0](/agentkit/connectors/snowflake/) [Connect to Snowflake to manage and analyze your data warehouse workloads](/agentkit/connectors/snowflake/) [scalekit42 tools](/agentkit/connectors/snowflake/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/snowflake.svg)](/agentkit/connectors/snowflakekeyauth/) [Snowflake Key Pair AuthBearer Token](/agentkit/connectors/snowflakekeyauth/) [Connect to Snowflake via Public Private Key Pair to manage and analyze your data warehouse workloads](/agentkit/connectors/snowflakekeyauth/) [scalekit42 tools](/agentkit/connectors/snowflakekeyauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/splice.svg)](/agentkit/connectors/splicemcp/) [Splice MCPOAuth 2.1/DCR](/agentkit/connectors/splicemcp/) [Connect to Splice MCP. Search the Splice sample catalog, create and update multi-track stacks, download audio assets, and generate arrangements from text...](/agentkit/connectors/splicemcp/) [Vendor MCP6 tools](/agentkit/connectors/splicemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sportradar.svg)](/agentkit/connectors/sportradarmcp/) [Sportradar MCPOAuth 2.1/DCR](/agentkit/connectors/sportradarmcp/) [Connect to Sportradar MCP. Browse and search sports data API specs, discover endpoints, check coverage, and access guide pages from your AI workflows.](/agentkit/connectors/sportradarmcp/) [Vendor MCP7 tools](/agentkit/connectors/sportradarmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stackai.svg)](/agentkit/connectors/stackaimcp/) [Stack.ai MCPOAuth 2.1/DCR](/agentkit/connectors/stackaimcp/) [Connect to Stack AI MCP. Build, run, and manage AI workflow projects, search knowledge bases, list integration providers, and inspect execution traces...](/agentkit/connectors/stackaimcp/) [Vendor MCP32 tools](/agentkit/connectors/stackaimcp/) [![](https://dac-static.atlassian.com/_static/Statuspage-blue.svg)](/agentkit/connectors/statuspage/) [StatuspageAPI Key](/agentkit/connectors/statuspage/) [Connect to Statuspage. Manage status pages, incidents, components, component groups, subscribers, metrics, and page access permissions.](/agentkit/connectors/statuspage/) [scalekit99 tools](/agentkit/connectors/statuspage/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/storeleads.svg)](/agentkit/connectors/storeleadsmcp/) [StoreLeads MCPBearer Token](/agentkit/connectors/storeleadsmcp/) [Connect to StoreLeads MCP to discover, search, and analyze e-commerce stores and their technology stack from your AI workflows.](/agentkit/connectors/storeleadsmcp/) [Vendor MCP16 tools](/agentkit/connectors/storeleadsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripe/) [StripeBearer Token](/agentkit/connectors/stripe/) [Connect to Stripe to manage customers, payments, products, subscriptions, invoices, and financial data.](/agentkit/connectors/stripe/) [scalekit178 tools](/agentkit/connectors/stripe/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripemcp/) [Stripe MCPOAuth 2.1/DCR](/agentkit/connectors/stripemcp/) [Connect to Stripe MCP. Manage customers, invoices, subscriptions, refunds, disputes, and payments from your AI workflows.](/agentkit/connectors/stripemcp/) [Vendor MCP10 tools](/agentkit/connectors/stripemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supabase.svg)](/agentkit/connectors/supabase/) [SupabaseOAuth 2.0](/agentkit/connectors/supabase/) [Connect to the Supabase Management API to manage organizations, projects, database branches, API keys, secrets, custom domains, network restrictions...](/agentkit/connectors/supabase/) [scalekit163 tools](/agentkit/connectors/supabase/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supabase.svg)](/agentkit/connectors/supabasemcp/) [Supabase MCPOAuth 2.1/DCR](/agentkit/connectors/supabasemcp/) [Connect to Supabase MCP. Manage projects, databases, branches, Edge Functions, migrations, and logs directly from your AI workflows.](/agentkit/connectors/supabasemcp/) [Vendor MCP29 tools](/agentkit/connectors/supabasemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadata/) [SupadataAPI Key](/agentkit/connectors/supadata/) [Connect with Supadata to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadata/) [scalekit21 tools](/agentkit/connectors/supadata/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadatamcp/) [Supadata MCPOAuth 2.1/DCR](/agentkit/connectors/supadatamcp/) [Connect with Supadata MCP to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadatamcp/) [Vendor MCP9 tools](/agentkit/connectors/supadatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supermetrics.svg)](/agentkit/connectors/supermetricsmcp/) [Supermetrics MCPOAuth 2.1/DCR](/agentkit/connectors/supermetricsmcp/) [Connect to Supermetrics MCP to query marketing data, discover data sources, manage campaigns, and run analytics across your connected ad and analytics...](/agentkit/connectors/supermetricsmcp/) [Vendor MCP14 tools](/agentkit/connectors/supermetricsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/surveymonkey.svg)](/agentkit/connectors/surveymonkeymcp/) [SurveyMonkey MCPOAuth 2.1/DCR](/agentkit/connectors/surveymonkeymcp/) [Connect to SurveyMonkey to manage surveys, collect responses, and analyze results. Create and update surveys, manage collectors and contacts, and retrieve...](/agentkit/connectors/surveymonkeymcp/) [Vendor MCP20 tools](/agentkit/connectors/surveymonkeymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/swagger.svg)](/agentkit/connectors/swaggermcp/) [Swagger MCPOAuth 2.1/DCR](/agentkit/connectors/swaggermcp/) [Connect to Swagger MCP. Create and manage APIs, developer portals, and documentation in SwaggerHub from AI workflows.](/agentkit/connectors/swaggermcp/) [Vendor MCP26 tools](/agentkit/connectors/swaggermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sybill.svg)](/agentkit/connectors/sybilmcp/) [Sybill MCPOAuth 2.1/DCR](/agentkit/connectors/sybilmcp/) [Connect to Sybill. Access AI-generated summaries of sales calls, deals, accounts, and conversations to accelerate B2B revenue workflows.](/agentkit/connectors/sybilmcp/) [Vendor MCP7 tools](/agentkit/connectors/sybilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synapse.svg)](/agentkit/connectors/synapsemcp/) [Synapse MCPOAuth 2.1/DCR](/agentkit/connectors/synapsemcp/) [Connect to the Synapse MCP server (Sage Bionetworks) to explore Synapse entities, annotations, provenance, and project structure, and to search...](/agentkit/connectors/synapsemcp/) [Vendor MCP48 tools](/agentkit/connectors/synapsemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synthesize-bio.svg)](/agentkit/connectors/synthesizebiomcp/) [Synthesize Bio MCPOAuth 2.1/DCR](/agentkit/connectors/synthesizebiomcp/) [Connect to Synthesize Bio MCP. Run differential gene expression analysis, resolve sample metadata, and retrieve results and raw counts data from your AI...](/agentkit/connectors/synthesizebiomcp/) [Vendor MCP5 tools](/agentkit/connectors/synthesizebiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tableau.svg)](/agentkit/connectors/tableau/) [TableauAPI Key](/agentkit/connectors/tableau/) [Connect to Tableau Cloud or Tableau Server to browse workbooks, views, and data sources, export visualizations, and query underlying data.](/agentkit/connectors/tableau/) [scalekit49 tools](/agentkit/connectors/tableau/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tactiq.svg)](/agentkit/connectors/tactiqmcp/) [Tactiq MCPOAuth 2.1/DCR](/agentkit/connectors/tactiqmcp/) [Tactiq captures and transcribes meetings in real time, turning conversations into AI-generated notes, summaries, and action items.](/agentkit/connectors/tactiqmcp/) [Vendor MCP9 tools](/agentkit/connectors/tactiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tally.svg)](/agentkit/connectors/tallymcp/) [Tally MCPOAuth 2.1/DCR](/agentkit/connectors/tallymcp/) [Connect to Tally MCP. Create and edit forms, manage submissions, and update styling and logic in your Tally workspace from AI workflows.](/agentkit/connectors/tallymcp/) [Vendor MCP26 tools](/agentkit/connectors/tallymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tango.svg)](/agentkit/connectors/tangomcp/) [Tango MCPAPI Key](/agentkit/connectors/tangomcp/) [Connect to Tango MCP by makegov to search federal contracts, opportunities, vehicles, organizations, and protests, and pull competitive...](/agentkit/connectors/tangomcp/) [Vendor MCP5 tools](/agentkit/connectors/tangomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tavily.svg)](/agentkit/connectors/tavilymcp/) [Tavily MCPOAuth 2.1/DCR](/agentkit/connectors/tavilymcp/) [Connect to Tavily MCP. Search the web, crawl websites, extract content, map site structure, and run deep research using Tavily's AI-powered search API.](/agentkit/connectors/tavilymcp/) [Vendor MCP5 tools](/agentkit/connectors/tavilymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft-teams.svg)](/agentkit/connectors/microsoftteams/) [TeamsOAuth 2.0](/agentkit/connectors/microsoftteams/) [Connect to Microsoft Teams. Manage messages, channels, meetings, and team collaboration](/agentkit/connectors/microsoftteams/) [scalekit82 tools](/agentkit/connectors/microsoftteams/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/telnyx.svg)](/agentkit/connectors/telnyxmcp/) [Telnyx MCPOAuth 2.1/DCR](/agentkit/connectors/telnyxmcp/) [Telnyx is a communications platform for voice, messaging, and AI. This MCP connector lets AI agents manage phone numbers, send SMS and MMS, place and...](/agentkit/connectors/telnyxmcp/) [Vendor MCP6 tools](/agentkit/connectors/telnyxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/testdino.svg)](/agentkit/connectors/testidinomcp/) [Testdino MCPOAuth 2.1/DCR](/agentkit/connectors/testidinomcp/) [TestDino is a Playwright test reporting and analytics platform that centralizes test data, detects flaky tests, and provides AI-powered debugging via MCP...](/agentkit/connectors/testidinomcp/) [Vendor MCP38 tools](/agentkit/connectors/testidinomcp/) [![]()](/agentkit/connectors/ticktickmcp/) [TickTick MCPOAuth 2.1/DCR](/agentkit/connectors/ticktickmcp/) [Connect to TickTick MCP. Manage tasks, projects, habits, and focus sessions in your TickTick account from AI workflows.](/agentkit/connectors/ticktickmcp/) [Vendor MCP50 tools](/agentkit/connectors/ticktickmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tinyfish.svg)](/agentkit/connectors/tinyfishmcp/) [Tinyfish MCPOAuth 2.1/DCR](/agentkit/connectors/tinyfishmcp/) [Connect to Tinyfish MCP. Run browser-based web automations, fetch page content, and search the web using a real cloud Chrome browser.](/agentkit/connectors/tinyfishmcp/) [Vendor MCP19 tools](/agentkit/connectors/tinyfishmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/todoist.svg)](/agentkit/connectors/todoistmcp/) [Todoist MCPOAuth 2.1/DCR](/agentkit/connectors/todoistmcp/) [Connect to Todoist MCP. Manage tasks, projects, sections, labels, filters, goals, and reminders from your AI workflows.](/agentkit/connectors/todoistmcp/) [Vendor MCP47 tools](/agentkit/connectors/todoistmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/topcounsel.svg)](/agentkit/connectors/topcounselmcp/) [TopCounsel MCPOAuth 2.1/DCR](/agentkit/connectors/topcounselmcp/) [Connect to TopCounsel by The L Suite to search, shortlist, and compare peer-vetted outside counsel recommendations grounded in firsthand feedback from...](/agentkit/connectors/topcounselmcp/) [Vendor MCP1 tool](/agentkit/connectors/topcounselmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trello/) [TrelloOAuth 1.0a](/agentkit/connectors/trello/) [Connect to Trello. Manage boards, cards, lists, and team collaboration workflows](/agentkit/connectors/trello/) [scalekit36 tools](/agentkit/connectors/trello/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trellomcp/) [Trello MCPOAuth 2.1/DCR](/agentkit/connectors/trellomcp/) [Connect to Trello's official MCP server to manage boards, cards, lists, and team collaboration workflows directly from your AI workflows.](/agentkit/connectors/trellomcp/) [Vendor MCP15 tools](/agentkit/connectors/trellomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/twelvedata.svg)](/agentkit/connectors/twelvedatamcp/) [Twelve Data MCPOAuth 2.1/DCR](/agentkit/connectors/twelvedatamcp/) [Connect to Twelve Data MCP for real-time and historical financial market data, including stock, forex, crypto, and ETF prices, technical indicators...](/agentkit/connectors/twelvedatamcp/) [Vendor MCP27 tools](/agentkit/connectors/twelvedatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/twilio.svg)](/agentkit/connectors/twilio/) [TwilioBasic Auth](/agentkit/connectors/twilio/) [Connect to Twilio to send SMS/MMS messages, make voice calls, verify phone numbers with OTP, manage phone numbers, and access usage records.](/agentkit/connectors/twilio/) [scalekit61 tools](/agentkit/connectors/twilio/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitter/) [Twitter / XBearer Token](/agentkit/connectors/twitter/) [Connect to Twitter. Read and write Tweets, read users, manage follows, bookmarks, etc.](/agentkit/connectors/twitter/) [scalekit104 tools](/agentkit/connectors/twitter/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitterbearer/) [Twitter / XBearer Token](/agentkit/connectors/twitterbearer/) [Connect to Twitter using an App-Only Bearer Token to access public, read-only, and application-level endpoints — search, compliance jobs and streams...](/agentkit/connectors/twitterbearer/) [scalekit44 tools](/agentkit/connectors/twitterbearer/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitteroauth/) [Twitter / XOAuth 2.0](/agentkit/connectors/twitteroauth/) [Connect to Twitter using OAuth 2.0 (Authorization Code with PKCE) to read and write Tweets on behalf of the authenticated user, manage users, follows...](/agentkit/connectors/twitteroauth/) [scalekit92 tools](/agentkit/connectors/twitteroauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/typeform.svg)](/agentkit/connectors/typeformmcp/) [Typeform MCPOAuth 2.1/DCR](/agentkit/connectors/typeformmcp/) [Connect to Typeform MCP to create and manage forms, read responses, and manage workspaces, contacts, and webhooks directly from your AI workflows.](/agentkit/connectors/typeformmcp/) [Vendor MCP63 tools](/agentkit/connectors/typeformmcp/) [![](https://framerusercontent.com/images/Pl7PUhW6GIt6eumE6hy3eKACaA.png)](/agentkit/connectors/upstreammcp/) [Upstream MCPBearer Token](/agentkit/connectors/upstreammcp/) [Connect to Upstream MCP to access AI-assistant tools and workflows, including inbox management, directly from your AI workflows.](/agentkit/connectors/upstreammcp/) [Vendor MCP46 tools](/agentkit/connectors/upstreammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/v0.svg)](/agentkit/connectors/v0mcp/) [v0 MCPBearer Token](/agentkit/connectors/v0mcp/) [Connect to v0 by Vercel to generate and iterate on web app UIs from natural language. Create chats, send follow-up messages, and inspect v0 Platform chats...](/agentkit/connectors/v0mcp/) [Vendor MCP5 tools](/agentkit/connectors/v0mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vapi.svg)](/agentkit/connectors/vapimcp/) [Vapi MCPBearer Token](/agentkit/connectors/vapimcp/) [Vapi is an AI-powered voice platform for building, testing, and deploying voice AI agents. This MCP connector enables AI agents to manage Vapi assistants...](/agentkit/connectors/vapimcp/) [Vendor MCP13 tools](/agentkit/connectors/vapimcp/) [![](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/vercel.svg)](/agentkit/connectors/vercel/) [VercelOAuth 2.0](/agentkit/connectors/vercel/) [Connect to Vercel. Access user profile, teams, projects, deployments, and environment settings.](/agentkit/connectors/vercel/) [scalekit83 tools](/agentkit/connectors/vercel/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vercel.svg)](/agentkit/connectors/vercelmcp/) [Vercel MCPOAuth 2.1](/agentkit/connectors/vercelmcp/) [Connect to Vercel MCP to manage deployments, projects, domains, environment variables, and team resources directly from your AI workflows.](/agentkit/connectors/vercelmcp/) [Vendor MCP34 tools](/agentkit/connectors/vercelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vibeprospecting.svg)](/agentkit/connectors/vibeprospectingmcp/) [Vibe Prospecting MCPOAuth 2.1/DCR](/agentkit/connectors/vibeprospectingmcp/) [Connect to Vibe Prospecting by Explorium to build B2B lead lists, research companies and prospects, enrich contacts, and personalize outreach from your AI...](/agentkit/connectors/vibeprospectingmcp/) [Vendor MCP14 tools](/agentkit/connectors/vibeprospectingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vimeo.svg)](/agentkit/connectors/vimeo/) [VimeoOAuth 2.0](/agentkit/connectors/vimeo/) [Connect to Vimeo API v3.4. Upload and manage videos, organize content into showcases and folders, manage channels, handle comments, likes, and webhooks.](/agentkit/connectors/vimeo/) [scalekit59 tools](/agentkit/connectors/vimeo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/webflow.svg)](/agentkit/connectors/webflowmcp/) [Webflow MCPOAuth 2.1/DCR](/agentkit/connectors/webflowmcp/) [Connect to Webflow. Build and manage websites, pages, components, styles, assets, CMS collections, and site settings through the Webflow Designer and Data...](/agentkit/connectors/webflowmcp/) [Vendor MCP40 tools](/agentkit/connectors/webflowmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/weflow.svg)](/agentkit/connectors/weflow/) [WeflowBearer Token](/agentkit/connectors/weflow/) [Connect to Weflow's Public API to read call and meeting recordings and their conversation intelligence data — transcripts, comments, clips, interaction...](/agentkit/connectors/weflow/) [scalekit11 tools](/agentkit/connectors/weflow/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whimsical.svg)](/agentkit/connectors/whimsicalmcp/) [Whimsical MCPOAuth 2.1/DCR](/agentkit/connectors/whimsicalmcp/) [Connect to Whimsical MCP. Create and edit flowcharts, mind maps, wireframes, and docs, and manage boards, comments, and workspaces from your AI workflows.](/agentkit/connectors/whimsicalmcp/) [Vendor MCP18 tools](/agentkit/connectors/whimsicalmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whop.svg)](/agentkit/connectors/whopmcp/) [Whop MCPOAuth 2.1/DCR](/agentkit/connectors/whopmcp/) [Whop is a platform for selling digital products, memberships, and communities.](/agentkit/connectors/whopmcp/) [Vendor MCP4 tools](/agentkit/connectors/whopmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/windsor.svg)](/agentkit/connectors/windsoraimcp/) [Windsor.ai MCPOAuth 2.1/DCR](/agentkit/connectors/windsoraimcp/) [Connect to Windsor.ai MCP to query unified marketing and business data pulled from 350+ connected sources, discover available fields and connectors...](/agentkit/connectors/windsoraimcp/) [Vendor MCP18 tools](/agentkit/connectors/windsoraimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wix.svg)](/agentkit/connectors/wixmcp/) [Wix MCPOAuth 2.1/DCR](/agentkit/connectors/wixmcp/) [Connect to Wix MCP. Build and manage Wix sites, call REST APIs, search documentation, upload media, and suggest domains from your AI workflows.](/agentkit/connectors/wixmcp/) [Vendor MCP26 tools](/agentkit/connectors/wixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wordpress.svg)](/agentkit/connectors/wordpressmcp/) [WordPress MCPOAuth 2.1/DCR](/agentkit/connectors/wordpressmcp/) [Connect to WordPress.com's official MCP server to manage posts, pages, comments, media, and site settings directly from your AI workflows.](/agentkit/connectors/wordpressmcp/) [Vendor MCP19 tools](/agentkit/connectors/wordpressmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/xero.svg)](/agentkit/connectors/xero/) [XeroOAuth 2.0](/agentkit/connectors/xero/) [Connect to Xero. Manage accounting, invoices, contacts, payments, bank transactions, and financial workflows](/agentkit/connectors/xero/) [scalekit94 tools](/agentkit/connectors/xero/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/you.svg)](/agentkit/connectors/youmcp/) [You.com MCPBearer Token](/agentkit/connectors/youmcp/) [Connect to You.com MCP. Search the web, research topics with cited sources, and extract full page content using You.com's AI-powered search and research...](/agentkit/connectors/youmcp/) [Vendor MCP6 tools](/agentkit/connectors/youmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/youtube.svg)](/agentkit/connectors/youtube/) [YouTubeOAuth 2.0](/agentkit/connectors/youtube/) [Connect to YouTube to access channel details, analytics, and upload or manage videos via OAuth 2.0](/agentkit/connectors/youtube/) [scalekit45 tools](/agentkit/connectors/youtube/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zapier.svg)](/agentkit/connectors/zapiermcp/) [Zapier MCPOAuth 2.1/DCR](/agentkit/connectors/zapiermcp/) [Connect to Zapier MCP to automate workflows and integrate with thousands of apps directly from your AI agent.](/agentkit/connectors/zapiermcp/) [Vendor MCP17 tools](/agentkit/connectors/zapiermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zendesk.svg)](/agentkit/connectors/zendesk/) [ZendeskAPI KEY](/agentkit/connectors/zendesk/) [Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations](/agentkit/connectors/zendesk/) [scalekit137 tools](/agentkit/connectors/zendesk/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zendesk.svg)](/agentkit/connectors/zendeskoauth/) [Zendesk (OAUTH)OAuth 2.0](/agentkit/connectors/zendeskoauth/) [Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations](/agentkit/connectors/zendeskoauth/) [scalekit137 tools](/agentkit/connectors/zendeskoauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zenrows.svg)](/agentkit/connectors/zenrowsmcp/) [ZenRows MCPOAuth 2.1/DCR](/agentkit/connectors/zenrowsmcp/) [Connect to ZenRows MCP. Scrape any webpage with anti-bot bypass, render JavaScript-heavy sites, and automate browsers through ZenRows' cloud...](/agentkit/connectors/zenrowsmcp/) [Vendor MCP43 tools](/agentkit/connectors/zenrowsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoho_crm.svg)](/agentkit/connectors/zohocrm/) [Zoho CRMOAuth 2.0](/agentkit/connectors/zohocrm/) [Connect to Zoho CRM. Manage leads, contacts, accounts, deals, tasks, and other sales activities.](/agentkit/connectors/zohocrm/) [scalekit89 tools](/agentkit/connectors/zohocrm/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoom.svg)](/agentkit/connectors/zoom/) [ZoomOAuth 2.0](/agentkit/connectors/zoom/) [Connect to Zoom. Schedule meetings, manage recordings, and handle video conferencing workflows](/agentkit/connectors/zoom/) [scalekit58 tools](/agentkit/connectors/zoom/) [![]()](/agentkit/connectors/zoomrevenueaccelerator/) [Zoom Revenue AcceleratorOAuth 2.0](/agentkit/connectors/zoomrevenueaccelerator/) [Connect to Zoom Revenue Accelerator (formerly Zoom IQ). Access sales conversation intelligence, deal insights, scorecards, CRM data imports, and team...](/agentkit/connectors/zoomrevenueaccelerator/) [scalekit50 tools](/agentkit/connectors/zoomrevenueaccelerator/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoominfo.svg)](/agentkit/connectors/zoominfo/) [ZoomInfoOAuth 2.0](/agentkit/connectors/zoominfo/) [Connect to ZoomInfo to search and enrich B2B contact and company data, access intent signals, discover technographic insights, and manage GTM Studio...](/agentkit/connectors/zoominfo/) [scalekit97 tools](/agentkit/connectors/zoominfo/) ## Tools ## Accounting & Finance [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carta.svg)](/agentkit/connectors/cartamcp/) [Carta MCPOAuth 2.1/DCR](/agentkit/connectors/cartamcp/) [Connect to Carta. Manage equity cap tables, fund administration, company accounts, and ownership data for venture-backed companies.](/agentkit/connectors/cartamcp/) [Vendor MCP18 tools](/agentkit/connectors/cartamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deel.svg)](/agentkit/connectors/deelmcp/) [Deel MCPOAuth 2.1/DCR](/agentkit/connectors/deelmcp/) [Global HR and payroll platform for hiring, paying, and managing international employees and contractors with built-in compliance.](/agentkit/connectors/deelmcp/) [Vendor MCP355 tools](/agentkit/connectors/deelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/digits.svg)](/agentkit/connectors/digitsmcp/) [Digits MCPOAuth 2.1/DCR](/agentkit/connectors/digitsmcp/) [Digits is an AI-powered business finance platform. This MCP connector gives AI agents read-only access to your Digits data — transactions, financial...](/agentkit/connectors/digitsmcp/) [Vendor MCP12 tools](/agentkit/connectors/digitsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dynamo.svg)](/agentkit/connectors/dynamo/) [Dynamo SoftwareBearer Token](/agentkit/connectors/dynamo/) [Connect to Dynamo Software API to access investment management, CRM, and reporting data.](/agentkit/connectors/dynamo/) [scalekit36 tools](/agentkit/connectors/dynamo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eodhd.svg)](/agentkit/connectors/eodhdmcp/) [EODHD MCPOAuth 2.1/DCR](/agentkit/connectors/eodhdmcp/) [EODHD (End of Day Historical Data) provides comprehensive financial market data including end-of-day stock prices, historical OHLCV data, fundamentals...](/agentkit/connectors/eodhdmcp/) [Vendor MCP91 tools](/agentkit/connectors/eodhdmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eracontext.svg)](/agentkit/connectors/eracontextmcp/) [Era Context MCPOAuth 2.1/DCR](/agentkit/connectors/eracontextmcp/) [Connect to Era Context MCP. Access personal finance data including transactions, accounts, spending insights, and AI-powered financial knowledge from Era.](/agentkit/connectors/eracontextmcp/) [Vendor MCP51 tools](/agentkit/connectors/eracontextmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/financialdatasets.svg)](/agentkit/connectors/financialdatasetsmcp/) [Financial Datasets MCPOAuth 2.1/DCR](/agentkit/connectors/financialdatasetsmcp/) [Financial Datasets provides an MCP interface to financial data APIs covering stock prices, financial statements, earnings, insider trades, and...](/agentkit/connectors/financialdatasetsmcp/) [Vendor MCP27 tools](/agentkit/connectors/financialdatasetsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fiscalai.svg)](/agentkit/connectors/fiscalaimcp/) [FiscalAI MCPOAuth 2.1/DCR](/agentkit/connectors/fiscalaimcp/) [Connect to FiscalAI MCP. Access financial data for public companies including SEC filings, earnings, stock prices, financial ratios, and company profiles.](/agentkit/connectors/fiscalaimcp/) [Vendor MCP2 tools](/agentkit/connectors/fiscalaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gocardless.svg)](/agentkit/connectors/gocardlessmcp/) [GoCardless MCPOAuth 2.1/DCR](/agentkit/connectors/gocardlessmcp/) [Connect to GoCardless MCP. Retrieve and list customers, mandates, payments, payouts, refunds, and subscriptions, and explore integration options from your...](/agentkit/connectors/gocardlessmcp/) [Vendor MCP24 tools](/agentkit/connectors/gocardlessmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gusto.svg)](/agentkit/connectors/gustomcp/) [Gusto MCPOAuth 2.1/DCR](/agentkit/connectors/gustomcp/) [Connect to Gusto MCP. Manage employees, contractors, payroll, departments, and company data from your AI workflows.](/agentkit/connectors/gustomcp/) [Vendor MCP50 tools](/agentkit/connectors/gustomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lunarcrush.svg)](/agentkit/connectors/lunarcrushmcp/) [Lunarcrush MCPOAuth 2.1/DCR](/agentkit/connectors/lunarcrushmcp/) [Connect to LunarCrush MCP. Access social intelligence, sentiment analytics, and market data for crypto assets from your AI workflows.](/agentkit/connectors/lunarcrushmcp/) [Vendor MCP15 tools](/agentkit/connectors/lunarcrushmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mercury.svg)](/agentkit/connectors/mercurymcp/) [Mercury MCPOAuth 2.1/DCR](/agentkit/connectors/mercurymcp/) [Connect to Mercury. Access accounts, transactions, recipients, invoices, treasury, webhooks, and approval requests for startup banking workflows.](/agentkit/connectors/mercurymcp/) [Vendor MCP35 tools](/agentkit/connectors/mercurymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/privacy.svg)](/agentkit/connectors/privacymcp/) [Privacy MCPOAuth 2.1/DCR](/agentkit/connectors/privacymcp/) [Connect to Privacy MCP. Create and manage virtual cards, set spend limits, pause or close cards, and review transactions from your AI workflows.](/agentkit/connectors/privacymcp/) [Vendor MCP10 tools](/agentkit/connectors/privacymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Quickbooks.svg)](/agentkit/connectors/quickbooks/) [QuickBooksOAuth 2.0](/agentkit/connectors/quickbooks/) [Connect to QuickBooks Online. Manage customers, vendors, invoices, bills, payments, and financial reports.](/agentkit/connectors/quickbooks/) [scalekit117 tools](/agentkit/connectors/quickbooks/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripe/) [StripeBearer Token](/agentkit/connectors/stripe/) [Connect to Stripe to manage customers, payments, products, subscriptions, invoices, and financial data.](/agentkit/connectors/stripe/) [scalekit178 tools](/agentkit/connectors/stripe/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripemcp/) [Stripe MCPOAuth 2.1/DCR](/agentkit/connectors/stripemcp/) [Connect to Stripe MCP. Manage customers, invoices, subscriptions, refunds, disputes, and payments from your AI workflows.](/agentkit/connectors/stripemcp/) [Vendor MCP10 tools](/agentkit/connectors/stripemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/twelvedata.svg)](/agentkit/connectors/twelvedatamcp/) [Twelve Data MCPOAuth 2.1/DCR](/agentkit/connectors/twelvedatamcp/) [Connect to Twelve Data MCP for real-time and historical financial market data, including stock, forex, crypto, and ETF prices, technical indicators...](/agentkit/connectors/twelvedatamcp/) [Vendor MCP27 tools](/agentkit/connectors/twelvedatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/xero.svg)](/agentkit/connectors/xero/) [XeroOAuth 2.0](/agentkit/connectors/xero/) [Connect to Xero. Manage accounting, invoices, contacts, payments, bank transactions, and financial workflows](/agentkit/connectors/xero/) [scalekit94 tools](/agentkit/connectors/xero/) ## AI [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adobe.svg)](/agentkit/connectors/adobemarketingagentmcp/) [Adobe Marketing Agent MCPOAuth 2.1/DCR](/agentkit/connectors/adobemarketingagentmcp/) [Connect to Adobe Marketing Cloud. Manage campaigns, analytics, and journeys using a natural-language AI assistant.](/agentkit/connectors/adobemarketingagentmcp/) [Vendor MCP12 tools](/agentkit/connectors/adobemarketingagentmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/affinda.svg)](/agentkit/connectors/affindamcp/) [Affinda MCPOAuth 2.1/DCR](/agentkit/connectors/affindamcp/) [AI-powered document processing platform that extracts, validates, and integrates structured data from invoices, resumes, contracts, and custom document...](/agentkit/connectors/affindamcp/) [Vendor MCP85 tools](/agentkit/connectors/affindamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agentmail.svg)](/agentkit/connectors/agentmailmcp/) [Agentmail MCPOAuth 2.1/DCR](/agentkit/connectors/agentmailmcp/) [Connect to Agentmail MCP. Manage inboxes, send and receive email, handle drafts, threads, and attachments from your AI workflows.](/agentkit/connectors/agentmailmcp/) [Vendor MCP26 tools](/agentkit/connectors/agentmailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airops.svg)](/agentkit/connectors/airopsmcp/) [Airops MCPAPI Key](/agentkit/connectors/airopsmcp/) [Connect to AirOps MCP. Manage brand kits, run AI-powered analytics, track AEO citations, and automate content workflows from your AI agents.](/agentkit/connectors/airopsmcp/) [Vendor MCP91 tools](/agentkit/connectors/airopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airparser.svg)](/agentkit/connectors/airparsermcp/) [Airparser MCPOAuth 2.1/DCR](/agentkit/connectors/airparsermcp/) [AI-powered document parser that extracts structured data from PDFs, emails, and other documents.](/agentkit/connectors/airparsermcp/) [Vendor MCP17 tools](/agentkit/connectors/airparsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/alphaxiv.svg)](/agentkit/connectors/alphaxivmcp/) [AlphaXiv MCPOAuth 2.1/DCR](/agentkit/connectors/alphaxivmcp/) [Connect to AlphaXiv MCP to search and retrieve arXiv research papers, abstracts, authors, and citations from your AI workflows.](/agentkit/connectors/alphaxivmcp/) [Vendor MCP18 tools](/agentkit/connectors/alphaxivmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anakin.svg)](/agentkit/connectors/anakinmcp/) [Anakin MCPOAuth 2.1/DCR](/agentkit/connectors/anakinmcp/) [Anakin is an AI platform and marketplace that lets you build, deploy, and access a wide range of AI tools and automated workflows. This MCP connector...](/agentkit/connectors/anakinmcp/) [Vendor MCP21 tools](/agentkit/connectors/anakinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anchorbrowser.svg)](/agentkit/connectors/anchorbrowsermcp/) [Anchor Browser MCPOAuth 2.1/DCR](/agentkit/connectors/anchorbrowsermcp/) [Connect to Anchor Browser MCP to run cloud browser automation, control live browser sessions, extract web data, and let AI agents browse and act on the...](/agentkit/connectors/anchorbrowsermcp/) [Vendor MCP25 tools](/agentkit/connectors/anchorbrowsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apify.svg)](/agentkit/connectors/apifymcp/) [Apify MCPBearer Token](/agentkit/connectors/apifymcp/) [Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows.](/agentkit/connectors/apifymcp/) [Vendor MCP11 tools](/agentkit/connectors/apifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attention.svg)](/agentkit/connectors/attention/) [AttentionAPI Key](/agentkit/connectors/attention/) [Connect to Attention for AI insights, conversations, teams, and workflows](/agentkit/connectors/attention/) [scalekit28 tools](/agentkit/connectors/attention/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biorendermcp.svg)](/agentkit/connectors/biorendermcp/) [Bio Render MCPOAuth 2.1/DCR](/agentkit/connectors/biorendermcp/) [Connect to BioRender MCP. Search BioRender's scientific icon and figure template libraries to build publication-ready biological illustrations.](/agentkit/connectors/biorendermcp/) [Vendor MCP2 tools](/agentkit/connectors/biorendermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitquery.svg)](/agentkit/connectors/bitquerymcp/) [Bitquery MCPOAuth 2.1/DCR](/agentkit/connectors/bitquerymcp/) [Connect to Bitquery MCP. Query on-chain DEX trading data, token prices, OHLCV series, trader profiles, and trending tokens across multiple blockchains...](/agentkit/connectors/bitquerymcp/) [Vendor MCP123 tools](/agentkit/connectors/bitquerymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brevo.svg)](/agentkit/connectors/brevomcp/) [Brevo MCPOAuth 2.1/DCR](/agentkit/connectors/brevomcp/) [Connect to Brevo MCP. Manage email and SMS campaigns, transactional emails, contacts, lists, automations, and loyalty programs from your AI workflows.](/agentkit/connectors/brevomcp/) [Vendor MCP282 tools](/agentkit/connectors/brevomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bugsnag.svg)](/agentkit/connectors/bugsnagmcp/) [Bugsnag MCPOAuth 2.1/DCR](/agentkit/connectors/bugsnagmcp/) [Connect to Bugsnag MCP. Monitor errors, releases, traces, and span groups across your projects from your AI workflows.](/agentkit/connectors/bugsnagmcp/) [Vendor MCP19 tools](/agentkit/connectors/bugsnagmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/buildkite.svg)](/agentkit/connectors/buildkitemcp/) [Buildkite MCPOAuth 2.1/DCR](/agentkit/connectors/buildkitemcp/) [Connect to Buildkite MCP. Manage CI/CD pipelines, builds, agents, clusters, and test suites from your AI workflows.](/agentkit/connectors/buildkitemcp/) [Vendor MCP51 tools](/agentkit/connectors/buildkitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cal.svg)](/agentkit/connectors/calmcp/) [Cal MCPOAuth 2.1/DCR](/agentkit/connectors/calmcp/) [Connect to Cal MCP. Manage bookings, event types, schedules, and availability from your AI workflows.](/agentkit/connectors/calmcp/) [Vendor MCP35 tools](/agentkit/connectors/calmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/candid.svg)](/agentkit/connectors/candidmcp/) [Candid MCPOAuth 2.1/DCR](/agentkit/connectors/candidmcp/) [Connect to Candid MCP. Search nonprofit organizations, explore philanthropic data, and classify social sector activities using Candid's knowledge base.](/agentkit/connectors/candidmcp/) [Vendor MCP6 tools](/agentkit/connectors/candidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carbone.svg)](/agentkit/connectors/carboneiomcp/) [Carbone.io MCPBearer Token](/agentkit/connectors/carboneiomcp/) [Connect to Carbone.io MCP. Upload templates, render documents by merging templates with JSON data, convert between 100+ formats, and manage template...](/agentkit/connectors/carboneiomcp/) [Vendor MCP11 tools](/agentkit/connectors/carboneiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chorus.svg)](/agentkit/connectors/chorus/) [ChorusBasic Auth](/agentkit/connectors/chorus/) [Connect to Chorus.ai to sync calls, transcripts, conversation intelligence, and analytics.](/agentkit/connectors/chorus/) [scalekit9 tools](/agentkit/connectors/chorus/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clari.svg)](/agentkit/connectors/clari_copilot/) [Clari CopilotAPI Key](/agentkit/connectors/clari_copilot/) [Connect to Clari Copilot for sales call transcripts, analytics, call data, and insights.](/agentkit/connectors/clari_copilot/) [scalekitComing soon](/agentkit/connectors/clari_copilot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cognee.svg)](/agentkit/connectors/cognee/) [CogneeAPI Key](/agentkit/connectors/cognee/) [Connect to Cognee, an AI memory engine for agents. Remember data into a knowledge graph, recall it with semantic search, improve stored memory, and forget...](/agentkit/connectors/cognee/) [scalekit18 tools](/agentkit/connectors/cognee/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/coinmarketcap.svg)](/agentkit/connectors/coinmarketcapmcp/) [CoinMarketCap MCPOAuth 2.1/DCR](/agentkit/connectors/coinmarketcapmcp/) [Connect to CoinMarketCap MCP. Access real-time crypto quotes, market metrics, technical analysis, trending narratives, and news from your AI workflows.](/agentkit/connectors/coinmarketcapmcp/) [Vendor MCP14 tools](/agentkit/connectors/coinmarketcapmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/context7.svg)](/agentkit/connectors/context7mcp/) [Context7 MCPAPI Key](/agentkit/connectors/context7mcp/) [Connect to Context7 MCP to fetch up-to-date, version-specific library documentation and code examples directly from the source.](/agentkit/connectors/context7mcp/) [Vendor MCP2 tools](/agentkit/connectors/context7mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/conversiontools.svg)](/agentkit/connectors/conversiontoolsmcp/) [Conversion Tools MCPOAuth 2.1/DCR](/agentkit/connectors/conversiontoolsmcp/) [Connect to Conversion Tools MCP. Convert files between 140+ formats including documents, images, audio, video, and data files from your AI workflows.](/agentkit/connectors/conversiontoolsmcp/) [Vendor MCP23 tools](/agentkit/connectors/conversiontoolsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dartai.svg)](/agentkit/connectors/dartaimcp/) [Dart AI MCPOAuth 2.1/DCR](/agentkit/connectors/dartaimcp/) [AI-native project management tool for task and document management with deep AI integration.](/agentkit/connectors/dartaimcp/) [Vendor MCP29 tools](/agentkit/connectors/dartaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dataforseo.svg)](/agentkit/connectors/dataforseomcp/) [Dataforseo MCPOAuth 2.1/DCR](/agentkit/connectors/dataforseomcp/) [Connect to DataForSEO. Access real-time SEO data including SERP results, keyword analytics, backlinks analysis, domain technologies, and AI visibility...](/agentkit/connectors/dataforseomcp/) [Vendor MCP90 tools](/agentkit/connectors/dataforseomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deepgram.svg)](/agentkit/connectors/deepgrammcp/) [Deepgram MCPOAuth 2.1/DCR](/agentkit/connectors/deepgrammcp/) [Connect to Deepgram MCP. Transcribe audio, generate speech, and manage transcription projects using Deepgram's AI-powered speech recognition API.](/agentkit/connectors/deepgrammcp/) [Vendor MCP1 tool](/agentkit/connectors/deepgrammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deepl.svg)](/agentkit/connectors/deeplmcp/) [DeepL MCPOAuth 2.1/DCR](/agentkit/connectors/deeplmcp/) [Connect to DeepL's MCP server to translate and rephrase text, correct grammar, translate documents, and manage glossaries and writing styles.](/agentkit/connectors/deeplmcp/) [Vendor MCP8 tools](/agentkit/connectors/deeplmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/descript.svg)](/agentkit/connectors/descriptmcp/) [Descript MCPOAuth 2.1/DCR](/agentkit/connectors/descriptmcp/) [Connect to Descript MCP. Import media, export transcripts, publish projects, run AI editing agents, and manage jobs from your AI workflows.](/agentkit/connectors/descriptmcp/) [Vendor MCP14 tools](/agentkit/connectors/descriptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devin.svg)](/agentkit/connectors/devinmcp/) [Devin MCPBearer Token](/agentkit/connectors/devinmcp/) [Connect to Devin MCP. Create and manage AI coding sessions, interact with Devin agents, manage playbooks and schedules, and browse repository wikis from...](/agentkit/connectors/devinmcp/) [Vendor MCP19 tools](/agentkit/connectors/devinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/digits.svg)](/agentkit/connectors/digitsmcp/) [Digits MCPOAuth 2.1/DCR](/agentkit/connectors/digitsmcp/) [Digits is an AI-powered business finance platform. This MCP connector gives AI agents read-only access to your Digits data — transactions, financial...](/agentkit/connectors/digitsmcp/) [Vendor MCP12 tools](/agentkit/connectors/digitsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dovetail.svg)](/agentkit/connectors/dovetailmcp/) [Dovetail MCPBearer Token](/agentkit/connectors/dovetailmcp/) [Connect to Dovetail, the AI-native UX research platform. Access projects, insights, and data from your AI workflows.](/agentkit/connectors/dovetailmcp/) [Vendor MCP44 tools](/agentkit/connectors/dovetailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eden.svg)](/agentkit/connectors/edenmcp/) [Eden MCPOAuth 2.1/DCR](/agentkit/connectors/edenmcp/) [Eden is an AI-powered content creation platform that discovers viral trends across 3M+ social media posts and helps creators generate content in their...](/agentkit/connectors/edenmcp/) [Vendor MCP84 tools](/agentkit/connectors/edenmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eodhd.svg)](/agentkit/connectors/eodhdmcp/) [EODHD MCPOAuth 2.1/DCR](/agentkit/connectors/eodhdmcp/) [EODHD (End of Day Historical Data) provides comprehensive financial market data including end-of-day stock prices, historical OHLCV data, fundamentals...](/agentkit/connectors/eodhdmcp/) [Vendor MCP91 tools](/agentkit/connectors/eodhdmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eracontext.svg)](/agentkit/connectors/eracontextmcp/) [Era Context MCPOAuth 2.1/DCR](/agentkit/connectors/eracontextmcp/) [Connect to Era Context MCP. Access personal finance data including transactions, accounts, spending insights, and AI-powered financial knowledge from Era.](/agentkit/connectors/eracontextmcp/) [Vendor MCP51 tools](/agentkit/connectors/eracontextmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/exa/) [ExaAPI Key](/agentkit/connectors/exa/) [Connect to Exa to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, run in-depth...](/agentkit/connectors/exa/) [scalekit21 tools](/agentkit/connectors/exa/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/examcp/) [Exa MCPAPI Key](/agentkit/connectors/examcp/) [Connect to Exa MCP to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, and run...](/agentkit/connectors/examcp/) [Vendor MCP2 tools](/agentkit/connectors/examcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathom/) [FathomAPI Key](/agentkit/connectors/fathom/) [Connect to Fathom AI meeting assistant. Record, transcribe, and summarize meetings with AI-powered insights](/agentkit/connectors/fathom/) [scalekit11 tools](/agentkit/connectors/fathom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathommcp/) [Fathom MCPOAuth 2.1/DCR](/agentkit/connectors/fathommcp/) [Connect to Fathom MCP to access AI meeting notes, summaries, transcripts, and recordings from your AI workflows.](/agentkit/connectors/fathommcp/) [Vendor MCP9 tools](/agentkit/connectors/fathommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/firecrawl.svg)](/agentkit/connectors/firecrawlmcp/) [Firecrawl MCPBearer Token](/agentkit/connectors/firecrawlmcp/) [Connect to Firecrawl MCP. Scrape, crawl, search, extract structured data, and monitor websites using Firecrawl's AI-powered web scraping API.](/agentkit/connectors/firecrawlmcp/) [Vendor MCP26 tools](/agentkit/connectors/firecrawlmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fiscalai.svg)](/agentkit/connectors/fiscalaimcp/) [FiscalAI MCPOAuth 2.1/DCR](/agentkit/connectors/fiscalaimcp/) [Connect to FiscalAI MCP. Access financial data for public companies including SEC filings, earnings, stock prices, financial ratios, and company profiles.](/agentkit/connectors/fiscalaimcp/) [Vendor MCP2 tools](/agentkit/connectors/fiscalaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/flux.svg)](/agentkit/connectors/fluxmcp/) [Flux MCPOAuth 2.1/DCR](/agentkit/connectors/fluxmcp/) [Flux by Black Forest Labs provides state-of-the-art AI image generation via the FLUX.1 family of models. Generate high-quality images from text prompts...](/agentkit/connectors/fluxmcp/) [Vendor MCP10 tools](/agentkit/connectors/fluxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gocardless.svg)](/agentkit/connectors/gocardlessmcp/) [GoCardless MCPOAuth 2.1/DCR](/agentkit/connectors/gocardlessmcp/) [Connect to GoCardless MCP. Retrieve and list customers, mandates, payments, payouts, refunds, and subscriptions, and explore integration options from your...](/agentkit/connectors/gocardlessmcp/) [Vendor MCP24 tools](/agentkit/connectors/gocardlessmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gong/) [GongOAuth 2.0](/agentkit/connectors/gong/) [Connect with Gong to sync calls, transcripts, insights, coaching and CRM activity](/agentkit/connectors/gong/) [scalekit49 tools](/agentkit/connectors/gong/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gongmcp/) [Gong MCPOAuth 2.1](/agentkit/connectors/gongmcp/) [Connect with Gong MCP to access calls, transcripts, insights, coaching, and sales engagement data via the Model Context Protocol](/agentkit/connectors/gongmcp/) [Vendor MCP3 tools](/agentkit/connectors/gongmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlecloudvision.svg)](/agentkit/connectors/googlecloudvision/) [Google Cloud VisionOAuth 2.0](/agentkit/connectors/googlecloudvision/) [Google Cloud Vision API lets you derive insights from images using pre-trained machine learning models — label detection, OCR/text extraction, face and...](/agentkit/connectors/googlecloudvision/) [scalekit27 tools](/agentkit/connectors/googlecloudvision/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grain/) [GrainBearer Token](/agentkit/connectors/grain/) [Grain's REST API for managing meeting recordings, transcripts, webhooks, and workspace data. Search and retrieve recordings and transcripts, upload and...](/agentkit/connectors/grain/) [scalekit19 tools](/agentkit/connectors/grain/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grainmcp/) [Grain MCPOAuth 2.1/DCR](/agentkit/connectors/grainmcp/) [Grain is a meeting recording and intelligence platform. Use this connector to search and retrieve meeting recordings, transcripts, notes, action items...](/agentkit/connectors/grainmcp/) [Vendor MCP41 tools](/agentkit/connectors/grainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granola/) [GranolaBearer Token](/agentkit/connectors/granola/) [Connect to Granola to access AI-generated meeting notes, summaries, transcripts, and attendee data from your workspace. Granola automatically records and...](/agentkit/connectors/granola/) [scalekit9 tools](/agentkit/connectors/granola/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granolamcp/) [Granola MCPOAuth 2.1/DCR](/agentkit/connectors/granolamcp/) [Connect to Granola MCP using OAuth 2.1 with MCP discovery and dynamic client registration.](/agentkit/connectors/granolamcp/) [Vendor MCP6 tools](/agentkit/connectors/granolamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/greptile.svg)](/agentkit/connectors/greptilmcp/) [Greptile MCPOAuth 2.1/DCR](/agentkit/connectors/greptilmcp/) [AI-powered code search and understanding API that indexes GitHub and GitLab repositories, enabling natural language queries over codebases.](/agentkit/connectors/greptilmcp/) [Vendor MCP16 tools](/agentkit/connectors/greptilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/happyscribe.svg)](/agentkit/connectors/happyscribemcp/) [HappyScribe MCPOAuth 2.1/DCR](/agentkit/connectors/happyscribemcp/) [HappyScribe is an AI-powered transcription and translation service. Connect your HappyScribe account to search transcripts, generate meeting summaries...](/agentkit/connectors/happyscribemcp/) [Vendor MCP39 tools](/agentkit/connectors/happyscribemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hex.svg)](/agentkit/connectors/hexmcp/) [Hex MCPOAuth 2.1/DCR](/agentkit/connectors/hexmcp/) [Connect to Hex MCP. Create and continue data analysis threads, search projects, and query your data using natural language from your AI workflows.](/agentkit/connectors/hexmcp/) [Vendor MCP5 tools](/agentkit/connectors/hexmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/higgsfield.svg)](/agentkit/connectors/higgsfieldmcp/) [Higgsfield MCPOAuth 2.1/DCR](/agentkit/connectors/higgsfieldmcp/) [Connect to Higgsfield MCP to generate AI images and videos, train consistent characters, and manage your creation history across 30+ models including...](/agentkit/connectors/higgsfieldmcp/) [Vendor MCP82 tools](/agentkit/connectors/higgsfieldmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/huggingface.svg)](/agentkit/connectors/huggingfacemcp/) [Hugging face MCPOAuth 2.1/DCR](/agentkit/connectors/huggingfacemcp/) [Connect to Hugging Face MCP. Search and manage models, datasets, spaces, and collections on the Hugging Face Hub.](/agentkit/connectors/huggingfacemcp/) [Vendor MCP11 tools](/agentkit/connectors/huggingfacemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/igpt.svg)](/agentkit/connectors/igptmcp/) [IGPT MCPOAuth 2.1/DCR](/agentkit/connectors/igptmcp/) [IGPT is an AI assistant platform that exposes its capabilities via an MCP server, enabling agents to interact with AI-powered tools and workflows.](/agentkit/connectors/igptmcp/) [Vendor MCP2 tools](/agentkit/connectors/igptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jam.svg)](/agentkit/connectors/jammcp/) [Jam MCPOAuth 2.1/DCR](/agentkit/connectors/jammcp/) [Connect to Jam MCP. Access bug reports, console logs, network requests, user events, and video transcripts from your AI workflows.](/agentkit/connectors/jammcp/) [Vendor MCP15 tools](/agentkit/connectors/jammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jentic.svg)](/agentkit/connectors/jenticmcp/) [Jentic MCPOAuth 2.1/DCR](/agentkit/connectors/jenticmcp/) [Connect to Jentic MCP. Search available API actions, load execution details, manage credentials, and execute API operations from your AI workflows.](/agentkit/connectors/jenticmcp/) [Vendor MCP4 tools](/agentkit/connectors/jenticmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jiminny.svg)](/agentkit/connectors/jiminny/) [JiminnyBearer Token](/agentkit/connectors/jiminny/) [Connect with Jiminny to access call recordings, transcripts, coaching insights, and conversation intelligence data.](/agentkit/connectors/jiminny/) [scalekit27 tools](/agentkit/connectors/jiminny/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kling.svg)](/agentkit/connectors/klingmcp/) [Kling AI MCPOAuth 2.1/DCR](/agentkit/connectors/klingmcp/) [Kling AI is a video and image generation platform. This MCP connector exposes Kling AI capabilities — including video generation and image generation —...](/agentkit/connectors/klingmcp/) [Vendor MCP10 tools](/agentkit/connectors/klingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/latch.svg)](/agentkit/connectors/latchbiomcp/) [Latch Bio MCPOAuth 2.1/DCR](/agentkit/connectors/latchbiomcp/) [Latch Bio is a cloud bioinformatics platform for running computational biology workflows. Its MCP server lets AI agents list and retrieve files, manage...](/agentkit/connectors/latchbiomcp/) [Vendor MCP9 tools](/agentkit/connectors/latchbiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lilt.svg)](/agentkit/connectors/liltmcp/) [LILT MCPOAuth 2.1/DCR](/agentkit/connectors/liltmcp/) [LILT is an enterprise translation platform that combines AI speed with human expertise to deliver accurate, domain-specific translations at scale. This...](/agentkit/connectors/liltmcp/) [Vendor MCP9 tools](/agentkit/connectors/liltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/listenlabs.svg)](/agentkit/connectors/listenlabsmcp/) [ListenLabs MCPOAuth 2.1/DCR](/agentkit/connectors/listenlabsmcp/) [Listen Labs is a qualitative research platform for creating, launching, and analyzing studies with AI assistance. This MCP connector gives AI agents...](/agentkit/connectors/listenlabsmcp/) [Vendor MCP13 tools](/agentkit/connectors/listenlabsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/loops.svg)](/agentkit/connectors/loopsmcp/) [Loops MCPOAuth 2.1/DCR](/agentkit/connectors/loopsmcp/) [Connect to Loops MCP. Create and manage loops and tasks, set priorities, track work queue stats, and ship completed loops from your AI workflows.](/agentkit/connectors/loopsmcp/) [Vendor MCP20 tools](/agentkit/connectors/loopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lunarcrush.svg)](/agentkit/connectors/lunarcrushmcp/) [Lunarcrush MCPOAuth 2.1/DCR](/agentkit/connectors/lunarcrushmcp/) [Connect to LunarCrush MCP. Access social intelligence, sentiment analytics, and market data for crypto assets from your AI workflows.](/agentkit/connectors/lunarcrushmcp/) [Vendor MCP15 tools](/agentkit/connectors/lunarcrushmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lusha.svg)](/agentkit/connectors/lushamcp/) [Lusha MCPAPI Key](/agentkit/connectors/lushamcp/) [Connect to Lusha MCP. Search and enrich B2B contacts and companies, find lookalikes, run prospecting searches, and access intent and activity signals from...](/agentkit/connectors/lushamcp/) [Vendor MCP37 tools](/agentkit/connectors/lushamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/magicpatterns.svg)](/agentkit/connectors/magicpatternsmcp/) [Magic Patterns MCPOAuth 2.1/DCR](/agentkit/connectors/magicpatternsmcp/) [Connect to Magic Patterns, the AI-powered UI design tool. Generate, edit, and manage design components and artifacts from your AI workflows.](/agentkit/connectors/magicpatternsmcp/) [Vendor MCP23 tools](/agentkit/connectors/magicpatternsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mem.svg)](/agentkit/connectors/memmcp/) [Mem MCPOAuth 2.1/DCR](/agentkit/connectors/memmcp/) [A hosted MCP server that gives AI tools secure access to your Mem notes and collections — enabling AI agents to read, create, search, and organize notes...](/agentkit/connectors/memmcp/) [Vendor MCP23 tools](/agentkit/connectors/memmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mem0.svg)](/agentkit/connectors/mem0mcp/) [Mem0 MCPOAuth 2.1/DCR](/agentkit/connectors/mem0mcp/) [Connect to Mem0 MCP. Store, search, and retrieve persistent memory for AI agents and applications using semantic search.](/agentkit/connectors/mem0mcp/) [Vendor MCP11 tools](/agentkit/connectors/mem0mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metaview.svg)](/agentkit/connectors/metaviewmcp/) [Metaview MCPOAuth 2.1/DCR](/agentkit/connectors/metaviewmcp/) [Metaview is an agentic recruiting platform that automates end-to-end hiring workflows — from candidate sourcing and outreach to interview note-taking and...](/agentkit/connectors/metaviewmcp/) [Vendor MCP46 tools](/agentkit/connectors/metaviewmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mintlify.svg)](/agentkit/connectors/mintlifymcp/) [Mintlify MCPOAuth 2.1/DCR](/agentkit/connectors/mintlifymcp/) [Connect to Mintlify MCP. Read and edit documentation pages, manage navigation nodes, search content, and publish changes via pull requests from your AI...](/agentkit/connectors/mintlifymcp/) [Vendor MCP19 tools](/agentkit/connectors/mintlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/momentum..svg)](/agentkit/connectors/momentum/) [MomentumAPI Key](/agentkit/connectors/momentum/) [Connect to Momentum, the AI-powered revenue intelligence platform. Retrieve meetings with attendee and transcript details, ingest and remap meetings, run...](/agentkit/connectors/momentum/) [scalekit8 tools](/agentkit/connectors/momentum/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motherduck.svg)](/agentkit/connectors/motherduckmcp/) [MotherDuck MCPOAuth 2.1/DCR](/agentkit/connectors/motherduckmcp/) [Connect to MotherDuck MCP. Query and analyze DuckDB databases, explore schemas, create visualizations, and automate data workflows from your AI workflows.](/agentkit/connectors/motherduckmcp/) [Vendor MCP44 tools](/agentkit/connectors/motherduckmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/neon.svg)](/agentkit/connectors/neonmcp/) [Neon MCPOAuth 2.1/DCR](/agentkit/connectors/neonmcp/) [Connect to Neon MCP. Manage Neon serverless Postgres databases, projects, branches, and queries from your AI workflows.](/agentkit/connectors/neonmcp/) [Vendor MCP35 tools](/agentkit/connectors/neonmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nimble.svg)](/agentkit/connectors/nimblemcp/) [Nimble MCPBearer Token](/agentkit/connectors/nimblemcp/) [Connect to Nimble MCP. Search the web across multiple engines, extract content from any URL, crawl websites at scale, discover all URLs on a site, and run...](/agentkit/connectors/nimblemcp/) [Vendor MCP31 tools](/agentkit/connectors/nimblemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/openrouter.svg)](/agentkit/connectors/openroutermcp/) [OpenRouter MCPOAuth 2.1/DCR](/agentkit/connectors/openroutermcp/) [Connect to OpenRouter's MCP server to access unified LLM routing, model discovery, and generation tools directly from your AI workflows.](/agentkit/connectors/openroutermcp/) [Vendor MCP23 tools](/agentkit/connectors/openroutermcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/parallel-ai.svg)](/agentkit/connectors/parallelaitaskmcp/) [Parallel AI Task MCPBearer Token](/agentkit/connectors/parallelaitaskmcp/) [Connect to Parallel AI Task MCP to run deep research tasks and task groups directly from your AI workflows.](/agentkit/connectors/parallelaitaskmcp/) [Vendor MCP4 tools](/agentkit/connectors/parallelaitaskmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/phantombuster.svg)](/agentkit/connectors/phantombuster/) [PhantomBusterAPI Key](/agentkit/connectors/phantombuster/) [Connect to PhantomBuster to automate web scraping and data extraction workflows. Launch, monitor, and manage automation agents that extract data from...](/agentkit/connectors/phantombuster/) [scalekit56 tools](/agentkit/connectors/phantombuster/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/phantombuster.svg)](/agentkit/connectors/phantombustermcp/) [PhantomBuster MCPOAuth 2.1/DCR](/agentkit/connectors/phantombustermcp/) [Connect to PhantomBuster MCP server to launch and manage web automation agents, retrieve scraping outputs, manage leads, and explore workspace resources...](/agentkit/connectors/phantombustermcp/) [Vendor MCP62 tools](/agentkit/connectors/phantombustermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planetscale.svg)](/agentkit/connectors/planetscalemcp/) [Planet Scale MCPOAuth 2.1/DCR](/agentkit/connectors/planetscalemcp/) [Connect to PlanetScale MCP. Run SQL queries, inspect database branches and schemas, get query performance insights, and manage organizations and invoices...](/agentkit/connectors/planetscalemcp/) [Vendor MCP16 tools](/agentkit/connectors/planetscalemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postman.svg)](/agentkit/connectors/postmanmcp/) [Postman MCPOAuth 2.1/DCR](/agentkit/connectors/postmanmcp/) [Connect to the Postman MCP server to manage collections, workspaces, environments, and APIs directly from your AI workflows.](/agentkit/connectors/postmanmcp/) [Vendor MCP41 tools](/agentkit/connectors/postmanmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/privacy.svg)](/agentkit/connectors/privacymcp/) [Privacy MCPOAuth 2.1/DCR](/agentkit/connectors/privacymcp/) [Connect to Privacy MCP. Create and manage virtual cards, set spend limits, pause or close cards, and review transactions from your AI workflows.](/agentkit/connectors/privacymcp/) [Vendor MCP10 tools](/agentkit/connectors/privacymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/profound.svg)](/agentkit/connectors/profoundmcp/) [Profound MCPOAuth 2.1/DCR](/agentkit/connectors/profoundmcp/) [Profound is an AI search visibility and marketing analytics platform that helps brands understand and optimize their presence across AI-powered answer...](/agentkit/connectors/profoundmcp/) [Vendor MCP15 tools](/agentkit/connectors/profoundmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quicknode.svg)](/agentkit/connectors/quicknodemcp/) [Quicknode MCPOAuth 2.1/DCR](/agentkit/connectors/quicknodemcp/) [Connect to QuickNode MCP. Create and manage blockchain RPC endpoints, configure security rules, set rate limits, and monitor usage and logs from your AI...](/agentkit/connectors/quicknodemcp/) [Vendor MCP19 tools](/agentkit/connectors/quicknodemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quizvideo.svg)](/agentkit/connectors/quizvideomcp/) [Quiz.Video MCPOAuth 2.1/DCR](/agentkit/connectors/quizvideomcp/) [Quiz.Video is an AI-powered platform for creating short-form quiz and flashcard videos. Transform topics, URLs, or documents into shareable quiz and...](/agentkit/connectors/quizvideomcp/) [Vendor MCP30 tools](/agentkit/connectors/quizvideomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/readai.svg)](/agentkit/connectors/readaimcp/) [Read AI MCPOAuth 2.1/DCR](/agentkit/connectors/readaimcp/) [Connect to Read AI to access your meeting intelligence — transcripts, summaries, action items, and insights from meetings, emails, and chats. Retrieve...](/agentkit/connectors/readaimcp/) [Vendor MCP4 tools](/agentkit/connectors/readaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/recraft.svg)](/agentkit/connectors/recraftmcp/) [Recraft AI MCPOAuth 2.1/DCR](/agentkit/connectors/recraftmcp/) [Connect to Recraft AI MCP. Generate AI-powered images, vectors, icons, and mockups from your AI agents using Recraft's creative design tools.](/agentkit/connectors/recraftmcp/) [Vendor MCP21 tools](/agentkit/connectors/recraftmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/replit.svg)](/agentkit/connectors/replitmcp/) [Replit MCPOAuth 2.1/DCR](/agentkit/connectors/replitmcp/) [Connect to Replit MCP. Create, update, and inspect Replit apps from natural-language prompts, list your apps, and resolve apps by name from your AI...](/agentkit/connectors/replitmcp/) [Vendor MCP8 tools](/agentkit/connectors/replitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/revealedai.svg)](/agentkit/connectors/revealedaimcp/) [Revealed AI MCPOAuth 2.1/DCR](/agentkit/connectors/revealedaimcp/) [Connect to Revealed AI. Track account signals, buyer personas, and people changes to surface timely outreach actions and account intelligence for B2B...](/agentkit/connectors/revealedaimcp/) [Vendor MCP13 tools](/agentkit/connectors/revealedaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/runware.svg)](/agentkit/connectors/runwaremcp/) [Runware MCPOAuth 2.1/DCR](/agentkit/connectors/runwaremcp/) [Connect to Runware's MCP server to generate and edit images, video, audio, and 3D assets using thousands of AI models through a single API.](/agentkit/connectors/runwaremcp/) [Vendor MCP12 tools](/agentkit/connectors/runwaremcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scrapfly.svg)](/agentkit/connectors/scarpflymcp/) [Scarpfly MCPOAuth 2.1/DCR](/agentkit/connectors/scarpflymcp/) [Connect to Scrapfly MCP. Scrape web pages, take screenshots, and control a cloud browser with anti-bot bypass, JS rendering, and proxy support.](/agentkit/connectors/scarpflymcp/) [Vendor MCP31 tools](/agentkit/connectors/scarpflymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scholargateway.svg)](/agentkit/connectors/scholargateway/) [Scholar Gateway MCPOAuth 2.1/DCR](/agentkit/connectors/scholargateway/) [Connect to Scholar Gateway to search Wiley's peer-reviewed academic literature — 8M+ articles from 2,000+ journals spanning sciences, healthcare...](/agentkit/connectors/scholargateway/) [scalekit1 tool](/agentkit/connectors/scholargateway/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smartling.svg)](/agentkit/connectors/smartlingmcp/) [Smartling MCPOAuth 2.1/DCR](/agentkit/connectors/smartlingmcp/) [Connect to Smartling MCP to manage translation projects, jobs, files, and glossaries, and run machine translation and localization workflows from your AI...](/agentkit/connectors/smartlingmcp/) [Vendor MCP53 tools](/agentkit/connectors/smartlingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/splice.svg)](/agentkit/connectors/splicemcp/) [Splice MCPOAuth 2.1/DCR](/agentkit/connectors/splicemcp/) [Connect to Splice MCP. Search the Splice sample catalog, create and update multi-track stacks, download audio assets, and generate arrangements from text...](/agentkit/connectors/splicemcp/) [Vendor MCP6 tools](/agentkit/connectors/splicemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sportradar.svg)](/agentkit/connectors/sportradarmcp/) [Sportradar MCPOAuth 2.1/DCR](/agentkit/connectors/sportradarmcp/) [Connect to Sportradar MCP. Browse and search sports data API specs, discover endpoints, check coverage, and access guide pages from your AI workflows.](/agentkit/connectors/sportradarmcp/) [Vendor MCP7 tools](/agentkit/connectors/sportradarmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stackai.svg)](/agentkit/connectors/stackaimcp/) [Stack.ai MCPOAuth 2.1/DCR](/agentkit/connectors/stackaimcp/) [Connect to Stack AI MCP. Build, run, and manage AI workflow projects, search knowledge bases, list integration providers, and inspect execution traces...](/agentkit/connectors/stackaimcp/) [Vendor MCP32 tools](/agentkit/connectors/stackaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadatamcp/) [Supadata MCPOAuth 2.1/DCR](/agentkit/connectors/supadatamcp/) [Connect with Supadata MCP to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadatamcp/) [Vendor MCP9 tools](/agentkit/connectors/supadatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sybill.svg)](/agentkit/connectors/sybilmcp/) [Sybill MCPOAuth 2.1/DCR](/agentkit/connectors/sybilmcp/) [Connect to Sybill. Access AI-generated summaries of sales calls, deals, accounts, and conversations to accelerate B2B revenue workflows.](/agentkit/connectors/sybilmcp/) [Vendor MCP7 tools](/agentkit/connectors/sybilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synthesize-bio.svg)](/agentkit/connectors/synthesizebiomcp/) [Synthesize Bio MCPOAuth 2.1/DCR](/agentkit/connectors/synthesizebiomcp/) [Connect to Synthesize Bio MCP. Run differential gene expression analysis, resolve sample metadata, and retrieve results and raw counts data from your AI...](/agentkit/connectors/synthesizebiomcp/) [Vendor MCP5 tools](/agentkit/connectors/synthesizebiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tactiq.svg)](/agentkit/connectors/tactiqmcp/) [Tactiq MCPOAuth 2.1/DCR](/agentkit/connectors/tactiqmcp/) [Tactiq captures and transcribes meetings in real time, turning conversations into AI-generated notes, summaries, and action items.](/agentkit/connectors/tactiqmcp/) [Vendor MCP9 tools](/agentkit/connectors/tactiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tavily.svg)](/agentkit/connectors/tavilymcp/) [Tavily MCPOAuth 2.1/DCR](/agentkit/connectors/tavilymcp/) [Connect to Tavily MCP. Search the web, crawl websites, extract content, map site structure, and run deep research using Tavily's AI-powered search API.](/agentkit/connectors/tavilymcp/) [Vendor MCP5 tools](/agentkit/connectors/tavilymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/telnyx.svg)](/agentkit/connectors/telnyxmcp/) [Telnyx MCPOAuth 2.1/DCR](/agentkit/connectors/telnyxmcp/) [Telnyx is a communications platform for voice, messaging, and AI. This MCP connector lets AI agents manage phone numbers, send SMS and MMS, place and...](/agentkit/connectors/telnyxmcp/) [Vendor MCP6 tools](/agentkit/connectors/telnyxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tinyfish.svg)](/agentkit/connectors/tinyfishmcp/) [Tinyfish MCPOAuth 2.1/DCR](/agentkit/connectors/tinyfishmcp/) [Connect to Tinyfish MCP. Run browser-based web automations, fetch page content, and search the web using a real cloud Chrome browser.](/agentkit/connectors/tinyfishmcp/) [Vendor MCP19 tools](/agentkit/connectors/tinyfishmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/v0.svg)](/agentkit/connectors/v0mcp/) [v0 MCPBearer Token](/agentkit/connectors/v0mcp/) [Connect to v0 by Vercel to generate and iterate on web app UIs from natural language. Create chats, send follow-up messages, and inspect v0 Platform chats...](/agentkit/connectors/v0mcp/) [Vendor MCP5 tools](/agentkit/connectors/v0mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vapi.svg)](/agentkit/connectors/vapimcp/) [Vapi MCPBearer Token](/agentkit/connectors/vapimcp/) [Vapi is an AI-powered voice platform for building, testing, and deploying voice AI agents. This MCP connector enables AI agents to manage Vapi assistants...](/agentkit/connectors/vapimcp/) [Vendor MCP13 tools](/agentkit/connectors/vapimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vibeprospecting.svg)](/agentkit/connectors/vibeprospectingmcp/) [Vibe Prospecting MCPOAuth 2.1/DCR](/agentkit/connectors/vibeprospectingmcp/) [Connect to Vibe Prospecting by Explorium to build B2B lead lists, research companies and prospects, enrich contacts, and personalize outreach from your AI...](/agentkit/connectors/vibeprospectingmcp/) [Vendor MCP14 tools](/agentkit/connectors/vibeprospectingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whimsical.svg)](/agentkit/connectors/whimsicalmcp/) [Whimsical MCPOAuth 2.1/DCR](/agentkit/connectors/whimsicalmcp/) [Connect to Whimsical MCP. Create and edit flowcharts, mind maps, wireframes, and docs, and manage boards, comments, and workspaces from your AI workflows.](/agentkit/connectors/whimsicalmcp/) [Vendor MCP18 tools](/agentkit/connectors/whimsicalmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wix.svg)](/agentkit/connectors/wixmcp/) [Wix MCPOAuth 2.1/DCR](/agentkit/connectors/wixmcp/) [Connect to Wix MCP. Build and manage Wix sites, call REST APIs, search documentation, upload media, and suggest domains from your AI workflows.](/agentkit/connectors/wixmcp/) [Vendor MCP26 tools](/agentkit/connectors/wixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/you.svg)](/agentkit/connectors/youmcp/) [You.com MCPBearer Token](/agentkit/connectors/youmcp/) [Connect to You.com MCP. Search the web, research topics with cited sources, and extract full page content using You.com's AI-powered search and research...](/agentkit/connectors/youmcp/) [Vendor MCP6 tools](/agentkit/connectors/youmcp/) [![]()](/agentkit/connectors/zoomrevenueaccelerator/) [Zoom Revenue AcceleratorOAuth 2.0](/agentkit/connectors/zoomrevenueaccelerator/) [Connect to Zoom Revenue Accelerator (formerly Zoom IQ). Access sales conversation intelligence, deal insights, scorecards, CRM data imports, and team...](/agentkit/connectors/zoomrevenueaccelerator/) [scalekit50 tools](/agentkit/connectors/zoomrevenueaccelerator/) ## Analytics [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adobe.svg)](/agentkit/connectors/adobemarketingagentmcp/) [Adobe Marketing Agent MCPOAuth 2.1/DCR](/agentkit/connectors/adobemarketingagentmcp/) [Connect to Adobe Marketing Cloud. Manage campaigns, analytics, and journeys using a natural-language AI assistant.](/agentkit/connectors/adobemarketingagentmcp/) [Vendor MCP12 tools](/agentkit/connectors/adobemarketingagentmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adzviser.svg)](/agentkit/connectors/adzvisermcp/) [Adzviser MCPOAuth 2.1/DCR](/agentkit/connectors/adzvisermcp/) [Connect to Adzviser MCP to query real-time marketing analytics across 46+ platforms - Google Ads, Facebook Ads, GA4, TikTok, LinkedIn, and more - from a...](/agentkit/connectors/adzvisermcp/) [Vendor MCP58 tools](/agentkit/connectors/adzvisermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agencyanalytics.svg)](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics MCPOAuth 2.1/DCR](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics is a marketing reporting platform that enables digital agencies to monitor SEO, PPC, social media, and other channel performance in...](/agentkit/connectors/agencyanalyticsmcp/) [Vendor MCP35 tools](/agentkit/connectors/agencyanalyticsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airbyte.svg)](/agentkit/connectors/airbytemcp/) [Airbyte MCPOAuth 2.1/DCR](/agentkit/connectors/airbytemcp/) [Connect to Airbyte's MCP server to manage data pipelines, sources, destinations, and connections for your data integration workflows.](/agentkit/connectors/airbytemcp/) [Vendor MCP20 tools](/agentkit/connectors/airbytemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airops.svg)](/agentkit/connectors/airopsmcp/) [Airops MCPAPI Key](/agentkit/connectors/airopsmcp/) [Connect to AirOps MCP. Manage brand kits, run AI-powered analytics, track AEO citations, and automate content workflows from your AI agents.](/agentkit/connectors/airopsmcp/) [Vendor MCP91 tools](/agentkit/connectors/airopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtable/) [AirtableOAuth 2.0](/agentkit/connectors/airtable/) [Connect to Airtable. Manage databases, tables, records, and collaborate on structured data](/agentkit/connectors/airtable/) [scalekit26 tools](/agentkit/connectors/airtable/) [![](https://akta.pro/favicon.ico?favicon.0_ooe5s20rw4w.ico)](/agentkit/connectors/aktapro/) [Akta ProAPI Key](/agentkit/connectors/aktapro/) [Connect to Akta Pro to search and monitor company news signals, including sentiment, entities, and industry classification, for sales and market...](/agentkit/connectors/aktapro/) [scalekit1 tool](/agentkit/connectors/aktapro/) [![](https://akta.pro/favicon.ico?favicon.0_ooe5s20rw4w.ico)](/agentkit/connectors/aktapromcp/) [Akta Pro MCPAPI Key](/agentkit/connectors/aktapromcp/) [Connect to Akta Pro MCP to search company news signals, check account status, and access sales intelligence tools directly from your AI agents.](/agentkit/connectors/aktapromcp/) [Vendor MCP17 tools](/agentkit/connectors/aktapromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/amplitude.svg)](/agentkit/connectors/amplitudeanalytics/) [Amplitude AnalyticsAPI Key + Secret Key](/agentkit/connectors/amplitudeanalytics/) [Connect to Amplitude's analytics REST APIs: event segmentation, funnels, cohorts, taxonomy, chart annotations, session replay, export, releases, streaming...](/agentkit/connectors/amplitudeanalytics/) [scalekit74 tools](/agentkit/connectors/amplitudeanalytics/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/amplitude.svg)](/agentkit/connectors/amplitudeexperimentmanagement/) [Amplitude Experiment ManagementBearer Token](/agentkit/connectors/amplitudeexperimentmanagement/) [Manage Amplitude Experiment feature flags, experiments, mutex groups, holdouts, and deployments. Separate connector from Experiment Evaluation (real-time...](/agentkit/connectors/amplitudeexperimentmanagement/) [scalekit57 tools](/agentkit/connectors/amplitudeexperimentmanagement/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/redshift.svg)](/agentkit/connectors/redshift/) [AWS RedshiftTrusted IDP](/agentkit/connectors/redshift/) [Amazon Redshift is a fully managed cloud data warehouse that enables fast, cost-effective analysis of structured and semi-structured data at scale.](/agentkit/connectors/redshift/) [scalekit10 tools](/agentkit/connectors/redshift/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/axiom.svg)](/agentkit/connectors/axiommcp/) [Axiom MCPOAuth 2.1/DCR](/agentkit/connectors/axiommcp/) [Axiom is a cloud-native data analytics and observability platform for ingesting, storing, and querying logs, events, traces, and metrics at scale. The MCP...](/agentkit/connectors/axiommcp/) [Vendor MCP26 tools](/agentkit/connectors/axiommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg)](/agentkit/connectors/bigqueryserviceaccount/) [BigQuery (Service Account)Service Account](/agentkit/connectors/bigqueryserviceaccount/) [Connect to Google BigQuery using a GCP service account for server-to-server authentication without user login.](/agentkit/connectors/bigqueryserviceaccount/) [scalekit26 tools](/agentkit/connectors/bigqueryserviceaccount/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biomni.svg)](/agentkit/connectors/biomnimcp/) [Biomni MCPOAuth 2.1/DCR](/agentkit/connectors/biomnimcp/) [Connect to Biomni MCP by phylo.bio, an AI biomedical research assistant. Analyze life-sciences data, interpret genomic variants, query curated databases...](/agentkit/connectors/biomnimcp/) [Vendor MCP12 tools](/agentkit/connectors/biomnimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitquery.svg)](/agentkit/connectors/bitquerymcp/) [Bitquery MCPOAuth 2.1/DCR](/agentkit/connectors/bitquerymcp/) [Connect to Bitquery MCP. Query on-chain DEX trading data, token prices, OHLCV series, trader profiles, and trending tokens across multiple blockchains...](/agentkit/connectors/bitquerymcp/) [Vendor MCP123 tools](/agentkit/connectors/bitquerymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brave.svg)](/agentkit/connectors/brave/) [Brave SearchAPI Key](/agentkit/connectors/brave/) [Connect to Brave Search to perform web, image, video, and news searches with privacy-focused results, plus AI-powered suggestions and spellcheck.](/agentkit/connectors/brave/) [scalekit18 tools](/agentkit/connectors/brave/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/builtwith.svg)](/agentkit/connectors/builtwithmcp/) [BuiltWith MCPBearer Token](/agentkit/connectors/builtwithmcp/) [BuiltWith tracks the technology stacks of millions of websites. The BuiltWith MCP server lets AI agents look up a site's technology profile, track...](/agentkit/connectors/builtwithmcp/) [Vendor MCP48 tools](/agentkit/connectors/builtwithmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carta.svg)](/agentkit/connectors/cartamcp/) [Carta MCPOAuth 2.1/DCR](/agentkit/connectors/cartamcp/) [Connect to Carta. Manage equity cap tables, fund administration, company accounts, and ownership data for venture-backed companies.](/agentkit/connectors/cartamcp/) [Vendor MCP18 tools](/agentkit/connectors/cartamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/catchr.svg)](/agentkit/connectors/catchrmcp/) [Catchr MCPOAuth 2.1/DCR](/agentkit/connectors/catchrmcp/) [Catchr is a data connector platform that syncs marketing and analytics data from ad platforms (Google Ads, Facebook Ads, etc.) to data warehouses and BI...](/agentkit/connectors/catchrmcp/) [Vendor MCP8 tools](/agentkit/connectors/catchrmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clarify.svg)](/agentkit/connectors/clarifymcp/) [Clarify MCPOAuth 2.1/DCR](/agentkit/connectors/clarifymcp/) [Connect to Clarify MCP to manage CRM records, leads, campaigns, lists, and analytics directly from your AI workflows.](/agentkit/connectors/clarifymcp/) [Vendor MCP38 tools](/agentkit/connectors/clarifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickhouse.svg)](/agentkit/connectors/clickhouse/) [Clickhouse MCPOAuth 2.1/DCR](/agentkit/connectors/clickhouse/) [Connect to ClickHouse MCP to query, analyze, and manage your ClickHouse databases directly from your AI workflows.](/agentkit/connectors/clickhouse/) [scalekit17 tools](/agentkit/connectors/clickhouse/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/coinmarketcap.svg)](/agentkit/connectors/coinmarketcapmcp/) [CoinMarketCap MCPOAuth 2.1/DCR](/agentkit/connectors/coinmarketcapmcp/) [Connect to CoinMarketCap MCP. Access real-time crypto quotes, market metrics, technical analysis, trending narratives, and news from your AI workflows.](/agentkit/connectors/coinmarketcapmcp/) [Vendor MCP14 tools](/agentkit/connectors/coinmarketcapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/commonroom.svg)](/agentkit/connectors/commonroommcp/) [Commonroom MCPOAuth 2.1/DCR](/agentkit/connectors/commonroommcp/) [Connect to Common Room MCP to manage community members, objects, and feedback data directly from your AI workflows.](/agentkit/connectors/commonroommcp/) [Vendor MCP5 tools](/agentkit/connectors/commonroommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/customerio.svg)](/agentkit/connectors/customeriomcp/) [Customer.io MCPOAuth 2.1/DCR](/agentkit/connectors/customeriomcp/) [Connect to Customer.io MCP to manage customers, campaigns, and events](/agentkit/connectors/customeriomcp/) [Vendor MCP8 tools](/agentkit/connectors/customeriomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databox.svg)](/agentkit/connectors/databoxmcp/) [Databox MCPOAuth 2.1/DCR](/agentkit/connectors/databoxmcp/) [Connect to Databox MCP. Query metrics, manage dashboards, and push custom data to your Databox analytics and reporting platform.](/agentkit/connectors/databoxmcp/) [Vendor MCP19 tools](/agentkit/connectors/databoxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databricks-1.svg)](/agentkit/connectors/databricksworkspace/) [Databricks WorkspaceService Principal (OAuth 2.0)](/agentkit/connectors/databricksworkspace/) [Connect to Databricks Workspace APIs using a Service Principal with OAuth 2.0 client credentials to manage clusters, jobs, notebooks, SQL, and more.](/agentkit/connectors/databricksworkspace/) [scalekit53 tools](/agentkit/connectors/databricksworkspace/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dataforseo.svg)](/agentkit/connectors/dataforseomcp/) [Dataforseo MCPOAuth 2.1/DCR](/agentkit/connectors/dataforseomcp/) [Connect to DataForSEO. Access real-time SEO data including SERP results, keyword analytics, backlinks analysis, domain technologies, and AI visibility...](/agentkit/connectors/dataforseomcp/) [Vendor MCP90 tools](/agentkit/connectors/dataforseomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/diarize.svg)](/agentkit/connectors/diarize/) [DiarizeBearer Token](/agentkit/connectors/diarize/) [Connect to Diarize to transcribe and diarize audio and video content from YouTube, X, Instagram, and TikTok. Submit transcription jobs and retrieve...](/agentkit/connectors/diarize/) [scalekit3 tools](/agentkit/connectors/diarize/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dovetail.svg)](/agentkit/connectors/dovetailmcp/) [Dovetail MCPBearer Token](/agentkit/connectors/dovetailmcp/) [Connect to Dovetail, the AI-native UX research platform. Access projects, insights, and data from your AI workflows.](/agentkit/connectors/dovetailmcp/) [Vendor MCP44 tools](/agentkit/connectors/dovetailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eodhd.svg)](/agentkit/connectors/eodhdmcp/) [EODHD MCPOAuth 2.1/DCR](/agentkit/connectors/eodhdmcp/) [EODHD (End of Day Historical Data) provides comprehensive financial market data including end-of-day stock prices, historical OHLCV data, fundamentals...](/agentkit/connectors/eodhdmcp/) [Vendor MCP91 tools](/agentkit/connectors/eodhdmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/exa/) [ExaAPI Key](/agentkit/connectors/exa/) [Connect to Exa to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, run in-depth...](/agentkit/connectors/exa/) [scalekit21 tools](/agentkit/connectors/exa/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/felt.svg)](/agentkit/connectors/feltmcp/) [FeltOAuth 2.1/DCR](/agentkit/connectors/feltmcp/) [Connect to Felt, a cloud-native GIS and mapping platform, to manage maps, layers, and geospatial data, query connected spatial databases, and collaborate...](/agentkit/connectors/feltmcp/) [Vendor MCP44 tools](/agentkit/connectors/feltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/financialdatasets.svg)](/agentkit/connectors/financialdatasetsmcp/) [Financial Datasets MCPOAuth 2.1/DCR](/agentkit/connectors/financialdatasetsmcp/) [Financial Datasets provides an MCP interface to financial data APIs covering stock prices, financial statements, earnings, insider trades, and...](/agentkit/connectors/financialdatasetsmcp/) [Vendor MCP27 tools](/agentkit/connectors/financialdatasetsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fiscalai.svg)](/agentkit/connectors/fiscalaimcp/) [FiscalAI MCPOAuth 2.1/DCR](/agentkit/connectors/fiscalaimcp/) [Connect to FiscalAI MCP. Access financial data for public companies including SEC filings, earnings, stock prices, financial ratios, and company profiles.](/agentkit/connectors/fiscalaimcp/) [Vendor MCP2 tools](/agentkit/connectors/fiscalaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gainsight.svg)](/agentkit/connectors/gainsight/) [GainsightAPI Key](/agentkit/connectors/gainsight/) [Connect to Gainsight Customer Success to manage companies, contacts, calls to action, success plans, timeline activities, and custom objects. Power...](/agentkit/connectors/gainsight/) [scalekit28 tools](/agentkit/connectors/gainsight/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googleanalytics.svg)](/agentkit/connectors/googleanalytics/) [Google AnalyticsOAuth 2.0](/agentkit/connectors/googleanalytics/) [Connect to Google Analytics (GA4) to run reports, realtime reports, and pivot reports, check dimension/metric compatibility, and manage audience exports...](/agentkit/connectors/googleanalytics/) [scalekit66 tools](/agentkit/connectors/googleanalytics/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg)](/agentkit/connectors/bigquery/) [Google BigQueryOAuth 2.0](/agentkit/connectors/bigquery/) [BigQuery is Google Cloud’s fully-managed enterprise data warehouse for analytics at scale.](/agentkit/connectors/bigquery/) [scalekit47 tools](/agentkit/connectors/bigquery/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google.svg)](/agentkit/connectors/googlebusinessprofile/) [Google Business ProfileOAuth 2.0](/agentkit/connectors/googlebusinessprofile/) [Google Business Profile lets businesses manage their presence across Google Search and Maps — business information, locations, performance/insights...](/agentkit/connectors/googlebusinessprofile/) [scalekit56 tools](/agentkit/connectors/googlebusinessprofile/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlelooker.svg)](/agentkit/connectors/googlelooker/) [Google LookerOAuth 2.0](/agentkit/connectors/googlelooker/) [Connect to Google Looker or self-hosted Looker Core. Browse dashboards, run Looks, query LookML models, and access BI data programmatically.](/agentkit/connectors/googlelooker/) [scalekit31 tools](/agentkit/connectors/googlelooker/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlesearch.svg)](/agentkit/connectors/googlesearchconsole/) [Google Search ConsoleOAuth 2.0](/agentkit/connectors/googlesearchconsole/) [Google Search Console (the Search Console API, formerly Webmaster Tools API) lets you monitor and manage a site's presence in Google Search results —...](/agentkit/connectors/googlesearchconsole/) [scalekit10 tools](/agentkit/connectors/googlesearchconsole/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_sheets.svg)](/agentkit/connectors/googlesheets/) [Google SheetsOAuth 2.0](/agentkit/connectors/googlesheets/) [Connect to Google Sheets. Create, edit, and analyze spreadsheets with powerful data management capabilities](/agentkit/connectors/googlesheets/) [scalekit48 tools](/agentkit/connectors/googlesheets/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gtmetrix.svg)](/agentkit/connectors/gtmetrixmcp/) [GTmetrix MCPOAuth 2.1/DCR](/agentkit/connectors/gtmetrixmcp/) [Connect to GTmetrix MCP to analyze web page performance, run speed tests, monitor Core Web Vitals, and get actionable optimization recommendations...](/agentkit/connectors/gtmetrixmcp/) [Vendor MCP10 tools](/agentkit/connectors/gtmetrixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/harvestapi.svg)](/agentkit/connectors/harvestapi/) [HarvestAPIAPI Key](/agentkit/connectors/harvestapi/) [Connect to HarvestAPI to scrape LinkedIn profiles, companies, and job listings, and search for people and jobs using LinkedIn data. Enables AI agents to...](/agentkit/connectors/harvestapi/) [scalekit25 tools](/agentkit/connectors/harvestapi/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hex.svg)](/agentkit/connectors/hexmcp/) [Hex MCPOAuth 2.1/DCR](/agentkit/connectors/hexmcp/) [Connect to Hex MCP. Create and continue data analysis threads, search projects, and query your data using natural language from your AI workflows.](/agentkit/connectors/hexmcp/) [Vendor MCP5 tools](/agentkit/connectors/hexmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hub_spot.svg)](/agentkit/connectors/hubspotmcp/) [HubSpot MCPOAuth 2.1](/agentkit/connectors/hubspotmcp/) [Connect to HubSpot MCP. Manage CRM contacts, companies, deals, landing pages, campaigns, and analytics from your AI workflows.](/agentkit/connectors/hubspotmcp/) [Vendor MCP22 tools](/agentkit/connectors/hubspotmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadboxer.svg)](/agentkit/connectors/leadboxermcp/) [LeadBoxer MCPOAuth 2.1/DCR](/agentkit/connectors/leadboxermcp/) [Connect to LeadBoxer MCP to identify anonymous website visitors and enrich them with firmographic data. LeadBoxer is a B2B lead generation and website...](/agentkit/connectors/leadboxermcp/) [Vendor MCP5 tools](/agentkit/connectors/leadboxermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadfeeder.svg)](/agentkit/connectors/leadfeedermcp/) [Leadfeeder MCPOAuth 2.1/DCR](/agentkit/connectors/leadfeedermcp/) [Connect to Leadfeeder's MCP server to identify website visitors, track B2B leads, and surface company-level intent data directly from your AI workflows.](/agentkit/connectors/leadfeedermcp/) [Vendor MCP58 tools](/agentkit/connectors/leadfeedermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadiq.svg)](/agentkit/connectors/leadiq/) [LeadIQAPI Key](/agentkit/connectors/leadiq/) [Connect to LeadIQ to search and enrich B2B contacts and companies with verified emails, direct dials, and mobile numbers. Build prospect lists and power...](/agentkit/connectors/leadiq/) [scalekit14 tools](/agentkit/connectors/leadiq/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadiq.svg)](/agentkit/connectors/leadiqmcp/) [LeadIQ MCPOAuth 2.1/DCR](/agentkit/connectors/leadiqmcp/) [Connect to LeadIQ via MCP to search and enrich B2B contacts and companies. Access real-time prospect data, company intelligence, and email/phone...](/agentkit/connectors/leadiqmcp/) [Vendor MCP16 tools](/agentkit/connectors/leadiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/legaldatahunter.svg)](/agentkit/connectors/legaldatahuntermcp/) [Legal Data Hunter MCPOAuth 2.1/DCR](/agentkit/connectors/legaldatahuntermcp/) [Connect to Legal Data Hunter MCP. Search and explore indexed legal data sources worldwide, tracking case law, courts, dockets, and legal data coverage...](/agentkit/connectors/legaldatahuntermcp/) [Vendor MCP7 tools](/agentkit/connectors/legaldatahuntermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkly.png)](/agentkit/connectors/linklymcp/) [LinklyHQ MCPOAuth 2.1/PKCE](/agentkit/connectors/linklymcp/) [LinklyHQ is a URL shortening and link management platform offering click analytics, custom domains, UTM tracking, QR codes, and webhook integrations for...](/agentkit/connectors/linklymcp/) [Vendor MCP25 tools](/agentkit/connectors/linklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/listenlabs.svg)](/agentkit/connectors/listenlabsmcp/) [ListenLabs MCPOAuth 2.1/DCR](/agentkit/connectors/listenlabsmcp/) [Listen Labs is a qualitative research platform for creating, launching, and analyzing studies with AI assistance. This MCP connector gives AI agents...](/agentkit/connectors/listenlabsmcp/) [Vendor MCP13 tools](/agentkit/connectors/listenlabsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/logrocket.svg)](/agentkit/connectors/logrocketmcp/) [LogRocket MCPOAuth 2.1/DCR](/agentkit/connectors/logrocketmcp/) [Connect to LogRocket to access session data, query analytics, investigate user-reported issues, and detect regressions directly from your AI workflows.](/agentkit/connectors/logrocketmcp/) [Vendor MCP8 tools](/agentkit/connectors/logrocketmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lunarcrush.svg)](/agentkit/connectors/lunarcrushmcp/) [Lunarcrush MCPOAuth 2.1/DCR](/agentkit/connectors/lunarcrushmcp/) [Connect to LunarCrush MCP. Access social intelligence, sentiment analytics, and market data for crypto assets from your AI workflows.](/agentkit/connectors/lunarcrushmcp/) [Vendor MCP15 tools](/agentkit/connectors/lunarcrushmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailchimp.svg)](/agentkit/connectors/mailchimp/) [MailchimpOAuth 2.0](/agentkit/connectors/mailchimp/) [Connect to Mailchimp to manage audiences, campaigns, templates, automations, and reports.](/agentkit/connectors/mailchimp/) [scalekit73 tools](/agentkit/connectors/mailchimp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mercury.svg)](/agentkit/connectors/mercurymcp/) [Mercury MCPOAuth 2.1/DCR](/agentkit/connectors/mercurymcp/) [Connect to Mercury. Access accounts, transactions, recipients, invoices, treasury, webhooks, and approval requests for startup banking workflows.](/agentkit/connectors/mercurymcp/) [Vendor MCP35 tools](/agentkit/connectors/mercurymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metricool.svg)](/agentkit/connectors/metricoolmcp/) [Metricool MCPOAuth 2.1/DCR](/agentkit/connectors/metricoolmcp/) [Metricool is a social media analytics and scheduling platform for managing, analyzing, and scheduling content across Instagram, Twitter/X, Facebook...](/agentkit/connectors/metricoolmcp/) [Vendor MCP9 tools](/agentkit/connectors/metricoolmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/excel.svg)](/agentkit/connectors/microsoftexcel/) [Microsoft ExcelOAuth 2.0](/agentkit/connectors/microsoftexcel/) [Connect to Microsoft Excel. Access, read, and modify spreadsheets stored in OneDrive or SharePoint through Microsoft Graph API.](/agentkit/connectors/microsoftexcel/) [scalekit47 tools](/agentkit/connectors/microsoftexcel/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixpanel.svg)](/agentkit/connectors/mixpanelanalytics/) [Mixpanel AnalyticsService Account](/agentkit/connectors/mixpanelanalytics/) [Connect to Mixpanel's Query API, Lexicon Schemas, and Warehouse Connectors to run segmentation, funnel, retention, and Insights reports, execute custom...](/agentkit/connectors/mixpanelanalytics/) [scalekit51 tools](/agentkit/connectors/mixpanelanalytics/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixpanel.svg)](/agentkit/connectors/mixpanelcompliance/) [Mixpanel ComplianceBearer Token](/agentkit/connectors/mixpanelcompliance/) [Connect to Mixpanel's GDPR/CCPA compliance API to submit and track end-user data deletion (right to erasure) and data retrieval (subject access) requests....](/agentkit/connectors/mixpanelcompliance/) [scalekit5 tools](/agentkit/connectors/mixpanelcompliance/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixpanel.svg)](/agentkit/connectors/mixpanelingestion/) [Mixpanel IngestionService Account](/agentkit/connectors/mixpanelingestion/) [Connect to Mixpanel's Ingestion API to track events, manage user and group profiles, resolve identities, replace lookup tables, and evaluate feature...](/agentkit/connectors/mixpanelingestion/) [scalekit25 tools](/agentkit/connectors/mixpanelingestion/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motherduck.svg)](/agentkit/connectors/motherduckmcp/) [MotherDuck MCPOAuth 2.1/DCR](/agentkit/connectors/motherduckmcp/) [Connect to MotherDuck MCP. Query and analyze DuckDB databases, explore schemas, create visualizations, and automate data workflows from your AI workflows.](/agentkit/connectors/motherduckmcp/) [Vendor MCP44 tools](/agentkit/connectors/motherduckmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pendo.svg)](/agentkit/connectors/pendomcp/) [Pendo MCPOAuth 2.1/DCR](/agentkit/connectors/pendomcp/) [Connect to Pendo MCP to access product analytics, user guidance, and engagement data directly from your AI workflows.](/agentkit/connectors/pendomcp/) [Vendor MCP45 tools](/agentkit/connectors/pendomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/posthog-1.svg)](/agentkit/connectors/posthogmcp/) [Posthog MCPOAuth 2.1/DCR](/agentkit/connectors/posthogmcp/) [Connect to Posthog MCP to enable your AI agents and tools to directly interact with PostHog's products.](/agentkit/connectors/posthogmcp/) [Vendor MCP200 tools](/agentkit/connectors/posthogmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/profound.svg)](/agentkit/connectors/profoundmcp/) [Profound MCPOAuth 2.1/DCR](/agentkit/connectors/profoundmcp/) [Profound is an AI search visibility and marketing analytics platform that helps brands understand and optimize their presence across AI-powered answer...](/agentkit/connectors/profoundmcp/) [Vendor MCP15 tools](/agentkit/connectors/profoundmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/proshortai.svg)](/agentkit/connectors/proshortai/) [ProShort AIAPI Key](/agentkit/connectors/proshortai/) [Connect to ProShort AI to search and retrieve AI-analyzed sales call recordings, transcripts, and summaries.](/agentkit/connectors/proshortai/) [scalekit5 tools](/agentkit/connectors/proshortai/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/revealedai.svg)](/agentkit/connectors/revealedaimcp/) [Revealed AI MCPOAuth 2.1/DCR](/agentkit/connectors/revealedaimcp/) [Connect to Revealed AI. Track account signals, buyer personas, and people changes to surface timely outreach actions and account intelligence for B2B...](/agentkit/connectors/revealedaimcp/) [Vendor MCP13 tools](/agentkit/connectors/revealedaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/rize.svg)](/agentkit/connectors/rizemcp/) [Rize MCPOAuth 2.1/DCR](/agentkit/connectors/rizemcp/) [Connect to Rize MCP using OAuth 2.1 with MCP discovery and dynamic client registration. Access and analyze your time tracking data, projects, clients...](/agentkit/connectors/rizemcp/) [Vendor MCP72 tools](/agentkit/connectors/rizemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/snowflake.svg)](/agentkit/connectors/snowflake/) [SnowflakeOAuth 2.0](/agentkit/connectors/snowflake/) [Connect to Snowflake to manage and analyze your data warehouse workloads](/agentkit/connectors/snowflake/) [scalekit42 tools](/agentkit/connectors/snowflake/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/snowflake.svg)](/agentkit/connectors/snowflakekeyauth/) [Snowflake Key Pair AuthBearer Token](/agentkit/connectors/snowflakekeyauth/) [Connect to Snowflake via Public Private Key Pair to manage and analyze your data warehouse workloads](/agentkit/connectors/snowflakekeyauth/) [scalekit42 tools](/agentkit/connectors/snowflakekeyauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sportradar.svg)](/agentkit/connectors/sportradarmcp/) [Sportradar MCPOAuth 2.1/DCR](/agentkit/connectors/sportradarmcp/) [Connect to Sportradar MCP. Browse and search sports data API specs, discover endpoints, check coverage, and access guide pages from your AI workflows.](/agentkit/connectors/sportradarmcp/) [Vendor MCP7 tools](/agentkit/connectors/sportradarmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/storeleads.svg)](/agentkit/connectors/storeleadsmcp/) [StoreLeads MCPBearer Token](/agentkit/connectors/storeleadsmcp/) [Connect to StoreLeads MCP to discover, search, and analyze e-commerce stores and their technology stack from your AI workflows.](/agentkit/connectors/storeleadsmcp/) [Vendor MCP16 tools](/agentkit/connectors/storeleadsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadata/) [SupadataAPI Key](/agentkit/connectors/supadata/) [Connect with Supadata to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadata/) [scalekit21 tools](/agentkit/connectors/supadata/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadatamcp/) [Supadata MCPOAuth 2.1/DCR](/agentkit/connectors/supadatamcp/) [Connect with Supadata MCP to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadatamcp/) [Vendor MCP9 tools](/agentkit/connectors/supadatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supermetrics.svg)](/agentkit/connectors/supermetricsmcp/) [Supermetrics MCPOAuth 2.1/DCR](/agentkit/connectors/supermetricsmcp/) [Connect to Supermetrics MCP to query marketing data, discover data sources, manage campaigns, and run analytics across your connected ad and analytics...](/agentkit/connectors/supermetricsmcp/) [Vendor MCP14 tools](/agentkit/connectors/supermetricsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/surveymonkey.svg)](/agentkit/connectors/surveymonkeymcp/) [SurveyMonkey MCPOAuth 2.1/DCR](/agentkit/connectors/surveymonkeymcp/) [Connect to SurveyMonkey to manage surveys, collect responses, and analyze results. Create and update surveys, manage collectors and contacts, and retrieve...](/agentkit/connectors/surveymonkeymcp/) [Vendor MCP20 tools](/agentkit/connectors/surveymonkeymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sybill.svg)](/agentkit/connectors/sybilmcp/) [Sybill MCPOAuth 2.1/DCR](/agentkit/connectors/sybilmcp/) [Connect to Sybill. Access AI-generated summaries of sales calls, deals, accounts, and conversations to accelerate B2B revenue workflows.](/agentkit/connectors/sybilmcp/) [Vendor MCP7 tools](/agentkit/connectors/sybilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synthesize-bio.svg)](/agentkit/connectors/synthesizebiomcp/) [Synthesize Bio MCPOAuth 2.1/DCR](/agentkit/connectors/synthesizebiomcp/) [Connect to Synthesize Bio MCP. Run differential gene expression analysis, resolve sample metadata, and retrieve results and raw counts data from your AI...](/agentkit/connectors/synthesizebiomcp/) [Vendor MCP5 tools](/agentkit/connectors/synthesizebiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tableau.svg)](/agentkit/connectors/tableau/) [TableauAPI Key](/agentkit/connectors/tableau/) [Connect to Tableau Cloud or Tableau Server to browse workbooks, views, and data sources, export visualizations, and query underlying data.](/agentkit/connectors/tableau/) [scalekit49 tools](/agentkit/connectors/tableau/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tango.svg)](/agentkit/connectors/tangomcp/) [Tango MCPAPI Key](/agentkit/connectors/tangomcp/) [Connect to Tango MCP by makegov to search federal contracts, opportunities, vehicles, organizations, and protests, and pull competitive...](/agentkit/connectors/tangomcp/) [Vendor MCP5 tools](/agentkit/connectors/tangomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/testdino.svg)](/agentkit/connectors/testidinomcp/) [Testdino MCPOAuth 2.1/DCR](/agentkit/connectors/testidinomcp/) [TestDino is a Playwright test reporting and analytics platform that centralizes test data, detects flaky tests, and provides AI-powered debugging via MCP...](/agentkit/connectors/testidinomcp/) [Vendor MCP38 tools](/agentkit/connectors/testidinomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/twelvedata.svg)](/agentkit/connectors/twelvedatamcp/) [Twelve Data MCPOAuth 2.1/DCR](/agentkit/connectors/twelvedatamcp/) [Connect to Twelve Data MCP for real-time and historical financial market data, including stock, forex, crypto, and ETF prices, technical indicators...](/agentkit/connectors/twelvedatamcp/) [Vendor MCP27 tools](/agentkit/connectors/twelvedatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/typeform.svg)](/agentkit/connectors/typeformmcp/) [Typeform MCPOAuth 2.1/DCR](/agentkit/connectors/typeformmcp/) [Connect to Typeform MCP to create and manage forms, read responses, and manage workspaces, contacts, and webhooks directly from your AI workflows.](/agentkit/connectors/typeformmcp/) [Vendor MCP63 tools](/agentkit/connectors/typeformmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/weflow.svg)](/agentkit/connectors/weflow/) [WeflowBearer Token](/agentkit/connectors/weflow/) [Connect to Weflow's Public API to read call and meeting recordings and their conversation intelligence data — transcripts, comments, clips, interaction...](/agentkit/connectors/weflow/) [scalekit11 tools](/agentkit/connectors/weflow/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/windsor.svg)](/agentkit/connectors/windsoraimcp/) [Windsor.ai MCPOAuth 2.1/DCR](/agentkit/connectors/windsoraimcp/) [Connect to Windsor.ai MCP to query unified marketing and business data pulled from 350+ connected sources, discover available fields and connectors...](/agentkit/connectors/windsoraimcp/) [Vendor MCP18 tools](/agentkit/connectors/windsoraimcp/) [![]()](/agentkit/connectors/zoomrevenueaccelerator/) [Zoom Revenue AcceleratorOAuth 2.0](/agentkit/connectors/zoomrevenueaccelerator/) [Connect to Zoom Revenue Accelerator (formerly Zoom IQ). Access sales conversation intelligence, deal insights, scorecards, CRM data imports, and team...](/agentkit/connectors/zoomrevenueaccelerator/) [scalekit50 tools](/agentkit/connectors/zoomrevenueaccelerator/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoominfo.svg)](/agentkit/connectors/zoominfo/) [ZoomInfoOAuth 2.0](/agentkit/connectors/zoominfo/) [Connect to ZoomInfo to search and enrich B2B contact and company data, access intent signals, discover technographic insights, and manage GTM Studio...](/agentkit/connectors/zoominfo/) [scalekit97 tools](/agentkit/connectors/zoominfo/) ## Automation [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/activepieces.svg)](/agentkit/connectors/activepiecesmcp/) [Activepieces MCPOAuth 2.1/DCR](/agentkit/connectors/activepiecesmcp/) [Connect to Activepieces MCP to trigger and manage no-code automation flows directly from your AI workflows.](/agentkit/connectors/activepiecesmcp/) [Vendor MCP44 tools](/agentkit/connectors/activepiecesmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airbyte.svg)](/agentkit/connectors/airbytemcp/) [Airbyte MCPOAuth 2.1/DCR](/agentkit/connectors/airbytemcp/) [Connect to Airbyte's MCP server to manage data pipelines, sources, destinations, and connections for your data integration workflows.](/agentkit/connectors/airbytemcp/) [Vendor MCP20 tools](/agentkit/connectors/airbytemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airparser.svg)](/agentkit/connectors/airparsermcp/) [Airparser MCPOAuth 2.1/DCR](/agentkit/connectors/airparsermcp/) [AI-powered document parser that extracts structured data from PDFs, emails, and other documents.](/agentkit/connectors/airparsermcp/) [Vendor MCP17 tools](/agentkit/connectors/airparsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anakin.svg)](/agentkit/connectors/anakinmcp/) [Anakin MCPOAuth 2.1/DCR](/agentkit/connectors/anakinmcp/) [Anakin is an AI platform and marketplace that lets you build, deploy, and access a wide range of AI tools and automated workflows. This MCP connector...](/agentkit/connectors/anakinmcp/) [Vendor MCP21 tools](/agentkit/connectors/anakinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anchorbrowser.svg)](/agentkit/connectors/anchorbrowsermcp/) [Anchor Browser MCPOAuth 2.1/DCR](/agentkit/connectors/anchorbrowsermcp/) [Connect to Anchor Browser MCP to run cloud browser automation, control live browser sessions, extract web data, and let AI agents browse and act on the...](/agentkit/connectors/anchorbrowsermcp/) [Vendor MCP25 tools](/agentkit/connectors/anchorbrowsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apify.svg)](/agentkit/connectors/apifymcp/) [Apify MCPBearer Token](/agentkit/connectors/apifymcp/) [Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows.](/agentkit/connectors/apifymcp/) [Vendor MCP11 tools](/agentkit/connectors/apifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attention.svg)](/agentkit/connectors/attention/) [AttentionAPI Key](/agentkit/connectors/attention/) [Connect to Attention for AI insights, conversations, teams, and workflows](/agentkit/connectors/attention/) [scalekit28 tools](/agentkit/connectors/attention/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/buildkite.svg)](/agentkit/connectors/buildkitemcp/) [Buildkite MCPOAuth 2.1/DCR](/agentkit/connectors/buildkitemcp/) [Connect to Buildkite MCP. Manage CI/CD pipelines, builds, agents, clusters, and test suites from your AI workflows.](/agentkit/connectors/buildkitemcp/) [Vendor MCP51 tools](/agentkit/connectors/buildkitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/catchr.svg)](/agentkit/connectors/catchrmcp/) [Catchr MCPOAuth 2.1/DCR](/agentkit/connectors/catchrmcp/) [Catchr is a data connector platform that syncs marketing and analytics data from ad platforms (Google Ads, Facebook Ads, etc.) to data warehouses and BI...](/agentkit/connectors/catchrmcp/) [Vendor MCP8 tools](/agentkit/connectors/catchrmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chilipiper.svg)](/agentkit/connectors/chilipipermcp/) [ChiliPiper MCPBearer Token](/agentkit/connectors/chilipipermcp/) [Connect to ChiliPiper MCP. Schedule meetings, manage routing rules, track distributions, and automate handoffs from your AI agents.](/agentkit/connectors/chilipipermcp/) [Vendor MCP156 tools](/agentkit/connectors/chilipipermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chorus.svg)](/agentkit/connectors/chorus/) [ChorusBasic Auth](/agentkit/connectors/chorus/) [Connect to Chorus.ai to sync calls, transcripts, conversation intelligence, and analytics.](/agentkit/connectors/chorus/) [scalekit9 tools](/agentkit/connectors/chorus/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clari.svg)](/agentkit/connectors/clari_copilot/) [Clari CopilotAPI Key](/agentkit/connectors/clari_copilot/) [Connect to Clari Copilot for sales call transcripts, analytics, call data, and insights.](/agentkit/connectors/clari_copilot/) [scalekitComing soon](/agentkit/connectors/clari_copilot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clay.svg)](/agentkit/connectors/claymcp/) [Clay MCPOAuth 2.1/DCR](/agentkit/connectors/claymcp/) [Clay is a go-to-market (GTM) platform that unifies data sourcing from 150+ providers, AI-powered research agents, and workflow orchestration for sales and...](/agentkit/connectors/claymcp/) [Vendor MCP17 tools](/agentkit/connectors/claymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudflare/) [CloudflareOAuth 2.0](/agentkit/connectors/cloudflare/) [Cloudflare is a cloud platform providing DNS management, CDN, security, and networking services. This connector enables automated management of zones, DNS...](/agentkit/connectors/cloudflare/) [scalekit31 tools](/agentkit/connectors/cloudflare/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudfaremcp/) [Cloudflare MCPOAuth 2.1/DCR](/agentkit/connectors/cloudfaremcp/) [Connect to Cloudflare MCP to manage your Cloudflare account — execute API calls, search the OpenAPI spec, and interact with Workers, R2, D1, KV, and all...](/agentkit/connectors/cloudfaremcp/) [Vendor MCP3 tools](/agentkit/connectors/cloudfaremcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/convertapi.svg)](/agentkit/connectors/convertapimcp/) [ConvertAPI MCPOAuth 2.1/DCR](/agentkit/connectors/convertapimcp/) [Connect to ConvertAPI MCP. Convert, merge, split, and transform files across 200+ formats including PDF, Word, Excel, images, and more.](/agentkit/connectors/convertapimcp/) [Vendor MCP5 tools](/agentkit/connectors/convertapimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databricks-1.svg)](/agentkit/connectors/databricksworkspace/) [Databricks WorkspaceService Principal (OAuth 2.0)](/agentkit/connectors/databricksworkspace/) [Connect to Databricks Workspace APIs using a Service Principal with OAuth 2.0 client credentials to manage clusters, jobs, notebooks, SQL, and more.](/agentkit/connectors/databricksworkspace/) [scalekit53 tools](/agentkit/connectors/databricksworkspace/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devin.svg)](/agentkit/connectors/devinmcp/) [Devin MCPBearer Token](/agentkit/connectors/devinmcp/) [Connect to Devin MCP. Create and manage AI coding sessions, interact with Devin agents, manage playbooks and schedules, and browse repository wikis from...](/agentkit/connectors/devinmcp/) [Vendor MCP19 tools](/agentkit/connectors/devinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/docsautomator.svg)](/agentkit/connectors/docsautomatormcp/) [Docsautomator MCPOAuth 2.1/DCR](/agentkit/connectors/docsautomatormcp/) [Connect to DocsAutomator MCP. Generate documents and PDFs from templates using your data, automating document creation workflows.](/agentkit/connectors/docsautomatormcp/) [Vendor MCP20 tools](/agentkit/connectors/docsautomatormcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/echtpost.svg)](/agentkit/connectors/echtpostmcp/) [Echtpost MCPOAuth 2.1/DCR](/agentkit/connectors/echtpostmcp/) [Connect to Echtpost MCP. Send physical postcards and letters programmatically via the Echtpost API.](/agentkit/connectors/echtpostmcp/) [Vendor MCP22 tools](/agentkit/connectors/echtpostmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/exa/) [ExaAPI Key](/agentkit/connectors/exa/) [Connect to Exa to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, run in-depth...](/agentkit/connectors/exa/) [scalekit21 tools](/agentkit/connectors/exa/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathom/) [FathomAPI Key](/agentkit/connectors/fathom/) [Connect to Fathom AI meeting assistant. Record, transcribe, and summarize meetings with AI-powered insights](/agentkit/connectors/fathom/) [scalekit11 tools](/agentkit/connectors/fathom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gong/) [GongOAuth 2.0](/agentkit/connectors/gong/) [Connect with Gong to sync calls, transcripts, insights, coaching and CRM activity](/agentkit/connectors/gong/) [scalekit49 tools](/agentkit/connectors/gong/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granola/) [GranolaBearer Token](/agentkit/connectors/granola/) [Connect to Granola to access AI-generated meeting notes, summaries, transcripts, and attendee data from your workspace. Granola automatically records and...](/agentkit/connectors/granola/) [scalekit9 tools](/agentkit/connectors/granola/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granolamcp/) [Granola MCPOAuth 2.1/DCR](/agentkit/connectors/granolamcp/) [Connect to Granola MCP using OAuth 2.1 with MCP discovery and dynamic client registration.](/agentkit/connectors/granolamcp/) [Vendor MCP6 tools](/agentkit/connectors/granolamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jentic.svg)](/agentkit/connectors/jenticmcp/) [Jentic MCPOAuth 2.1/DCR](/agentkit/connectors/jenticmcp/) [Connect to Jentic MCP. Search available API actions, load execution details, manage credentials, and execute API operations from your AI workflows.](/agentkit/connectors/jenticmcp/) [Vendor MCP4 tools](/agentkit/connectors/jenticmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jiminny.svg)](/agentkit/connectors/jiminny/) [JiminnyBearer Token](/agentkit/connectors/jiminny/) [Connect with Jiminny to access call recordings, transcripts, coaching insights, and conversation intelligence data.](/agentkit/connectors/jiminny/) [scalekit27 tools](/agentkit/connectors/jiminny/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jotform.svg)](/agentkit/connectors/jotformmcp/) [Jotform MCPOAuth 2.1/DCR](/agentkit/connectors/jotformmcp/) [Connect to Jotform MCP. Create and edit forms, retrieve submissions, assign forms, and search assets from your AI workflows.](/agentkit/connectors/jotformmcp/) [Vendor MCP7 tools](/agentkit/connectors/jotformmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kit.svg)](/agentkit/connectors/kitmcp/) [Kit MCPOAuth 2.1/DCR](/agentkit/connectors/kitmcp/) [Connect to Kit MCP. Manage email subscribers, sequences, broadcasts, tags, and forms for your email marketing workflows.](/agentkit/connectors/kitmcp/) [Vendor MCP81 tools](/agentkit/connectors/kitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/launchdarkly.svg)](/agentkit/connectors/launchdarklymcp/) [LaunchDarkly MCPOAuth 2.1/DCR](/agentkit/connectors/launchdarklymcp/) [Connect to LaunchDarkly's hosted MCP server to manage feature flags, experiments, and release controls directly from your AI workflows.](/agentkit/connectors/launchdarklymcp/) [Vendor MCP136 tools](/agentkit/connectors/launchdarklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailchimp.svg)](/agentkit/connectors/mailchimp/) [MailchimpOAuth 2.0](/agentkit/connectors/mailchimp/) [Connect to Mailchimp to manage audiences, campaigns, templates, automations, and reports.](/agentkit/connectors/mailchimp/) [scalekit73 tools](/agentkit/connectors/mailchimp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailercloud.svg)](/agentkit/connectors/mailercloudmcp/) [Mailercloud MCPOAuth 2.1/DCR](/agentkit/connectors/mailercloudmcp/) [Connect to Mailer Cloud MCP. Manage email campaigns, subscriber lists, and automation workflows for your email marketing operations.](/agentkit/connectors/mailercloudmcp/) [Vendor MCP47 tools](/agentkit/connectors/mailercloudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailerlite.svg)](/agentkit/connectors/mailerlitemcp/) [Mailerlite MCPOAuth 2.1/DCR](/agentkit/connectors/mailerlitemcp/) [Connect to MailerLite MCP. Manage email campaigns, subscribers, groups, automations, and forms from your AI workflows.](/agentkit/connectors/mailerlitemcp/) [Vendor MCP77 tools](/agentkit/connectors/mailerlitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/make.svg)](/agentkit/connectors/makemcp/) [Make MCPOAuth 2.1/DCR](/agentkit/connectors/makemcp/) [Connect to Make (formerly Integromat). Build, run, and manage automation scenarios, data stores, webhooks, and connections across thousands of apps from...](/agentkit/connectors/makemcp/) [Vendor MCP163 tools](/agentkit/connectors/makemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/memberstack.svg)](/agentkit/connectors/memberstackmcp/) [Memberstack MCPOAuth 2.1/DCR](/agentkit/connectors/memberstackmcp/) [Connect to Memberstack MCP. Manage members, plans, form submissions, and permissions for your membership-based application.](/agentkit/connectors/memberstackmcp/) [Vendor MCP69 tools](/agentkit/connectors/memberstackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/netlify.svg)](/agentkit/connectors/netlifymcp/) [Netlify MCPOAuth 2.1/DCR](/agentkit/connectors/netlifymcp/) [Build, deploy, and manage Netlify projects — sites, functions, environment variables, forms, blobs, and edge functions — from AI agents via the Netlify...](/agentkit/connectors/netlifymcp/) [Vendor MCP9 tools](/agentkit/connectors/netlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pandadoc.svg)](/agentkit/connectors/pandadocmcp/) [Pandadoc MCPOAuth 2.1/DCR](/agentkit/connectors/pandadocmcp/) [Connect to PandaDoc MCP. Create, send, and manage documents, templates, and e-signatures directly from your AI workflows.](/agentkit/connectors/pandadocmcp/) [Vendor MCP22 tools](/agentkit/connectors/pandadocmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/phantombuster.svg)](/agentkit/connectors/phantombuster/) [PhantomBusterAPI Key](/agentkit/connectors/phantombuster/) [Connect to PhantomBuster to automate web scraping and data extraction workflows. Launch, monitor, and manage automation agents that extract data from...](/agentkit/connectors/phantombuster/) [scalekit56 tools](/agentkit/connectors/phantombuster/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/phantombuster.svg)](/agentkit/connectors/phantombustermcp/) [PhantomBuster MCPOAuth 2.1/DCR](/agentkit/connectors/phantombustermcp/) [Connect to PhantomBuster MCP server to launch and manage web automation agents, retrieve scraping outputs, manage leads, and explore workspace resources...](/agentkit/connectors/phantombustermcp/) [Vendor MCP62 tools](/agentkit/connectors/phantombustermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postman.svg)](/agentkit/connectors/postmanmcp/) [Postman MCPOAuth 2.1/DCR](/agentkit/connectors/postmanmcp/) [Connect to the Postman MCP server to manage collections, workspaces, environments, and APIs directly from your AI workflows.](/agentkit/connectors/postmanmcp/) [Vendor MCP41 tools](/agentkit/connectors/postmanmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/prohostai.svg)](/agentkit/connectors/prohostaimcp/) [ProhostAI MCPOAuth 2.1/DCR](/agentkit/connectors/prohostaimcp/) [ProhostAI is an AI-powered property management platform for Airbnb hosts and property managers, offering AI guest messaging, task/cleaning automation...](/agentkit/connectors/prohostaimcp/) [Vendor MCP268 tools](/agentkit/connectors/prohostaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/replit.svg)](/agentkit/connectors/replitmcp/) [Replit MCPOAuth 2.1/DCR](/agentkit/connectors/replitmcp/) [Connect to Replit MCP. Create, update, and inspect Replit apps from natural-language prompts, list your apps, and resolve apps by name from your AI...](/agentkit/connectors/replitmcp/) [Vendor MCP8 tools](/agentkit/connectors/replitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sales_force.svg)](/agentkit/connectors/salesforcemarketingcloud/) [Salesforce Marketing CloudOAuth 2.0 Server-to-Server](/agentkit/connectors/salesforcemarketingcloud/) [Connect to Salesforce Marketing Cloud to manage contacts, data extensions, automations, journeys, and email/SMS/push sends across your marketing programs.](/agentkit/connectors/salesforcemarketingcloud/) [scalekit209 tools](/agentkit/connectors/salesforcemarketingcloud/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/salesloft.svg)](/agentkit/connectors/salesloft/) [SalesloftOAuth 2.0](/agentkit/connectors/salesloft/) [Connect with Salesloft to manage people, cadences, accounts, activities, emails, calls, and notes](/agentkit/connectors/salesloft/) [scalekit56 tools](/agentkit/connectors/salesloft/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/signwell.svg)](/agentkit/connectors/signwell/) [SignWellAPI Key](/agentkit/connectors/signwell/) [SignWell is an e-signature platform for sending, signing, and managing documents. Connect to create and send documents for signature, manage templates...](/agentkit/connectors/signwell/) [scalekit26 tools](/agentkit/connectors/signwell/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stackai.svg)](/agentkit/connectors/stackaimcp/) [Stack.ai MCPOAuth 2.1/DCR](/agentkit/connectors/stackaimcp/) [Connect to Stack AI MCP. Build, run, and manage AI workflow projects, search knowledge bases, list integration providers, and inspect execution traces...](/agentkit/connectors/stackaimcp/) [Vendor MCP32 tools](/agentkit/connectors/stackaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripe/) [StripeBearer Token](/agentkit/connectors/stripe/) [Connect to Stripe to manage customers, payments, products, subscriptions, invoices, and financial data.](/agentkit/connectors/stripe/) [scalekit178 tools](/agentkit/connectors/stripe/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripemcp/) [Stripe MCPOAuth 2.1/DCR](/agentkit/connectors/stripemcp/) [Connect to Stripe MCP. Manage customers, invoices, subscriptions, refunds, disputes, and payments from your AI workflows.](/agentkit/connectors/stripemcp/) [Vendor MCP10 tools](/agentkit/connectors/stripemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tally.svg)](/agentkit/connectors/tallymcp/) [Tally MCPOAuth 2.1/DCR](/agentkit/connectors/tallymcp/) [Connect to Tally MCP. Create and edit forms, manage submissions, and update styling and logic in your Tally workspace from AI workflows.](/agentkit/connectors/tallymcp/) [Vendor MCP26 tools](/agentkit/connectors/tallymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tinyfish.svg)](/agentkit/connectors/tinyfishmcp/) [Tinyfish MCPOAuth 2.1/DCR](/agentkit/connectors/tinyfishmcp/) [Connect to Tinyfish MCP. Run browser-based web automations, fetch page content, and search the web using a real cloud Chrome browser.](/agentkit/connectors/tinyfishmcp/) [Vendor MCP19 tools](/agentkit/connectors/tinyfishmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/twilio.svg)](/agentkit/connectors/twilio/) [TwilioBasic Auth](/agentkit/connectors/twilio/) [Connect to Twilio to send SMS/MMS messages, make voice calls, verify phone numbers with OTP, manage phone numbers, and access usage records.](/agentkit/connectors/twilio/) [scalekit61 tools](/agentkit/connectors/twilio/) [![](https://framerusercontent.com/images/Pl7PUhW6GIt6eumE6hy3eKACaA.png)](/agentkit/connectors/upstreammcp/) [Upstream MCPBearer Token](/agentkit/connectors/upstreammcp/) [Connect to Upstream MCP to access AI-assistant tools and workflows, including inbox management, directly from your AI workflows.](/agentkit/connectors/upstreammcp/) [Vendor MCP46 tools](/agentkit/connectors/upstreammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zapier.svg)](/agentkit/connectors/zapiermcp/) [Zapier MCPOAuth 2.1/DCR](/agentkit/connectors/zapiermcp/) [Connect to Zapier MCP to automate workflows and integrate with thousands of apps directly from your AI agent.](/agentkit/connectors/zapiermcp/) [Vendor MCP17 tools](/agentkit/connectors/zapiermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zenrows.svg)](/agentkit/connectors/zenrowsmcp/) [ZenRows MCPOAuth 2.1/DCR](/agentkit/connectors/zenrowsmcp/) [Connect to ZenRows MCP. Scrape any webpage with anti-bot bypass, render JavaScript-heavy sites, and automate browsers through ZenRows' cloud...](/agentkit/connectors/zenrowsmcp/) [Vendor MCP43 tools](/agentkit/connectors/zenrowsmcp/) ## Calendar [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cal.svg)](/agentkit/connectors/calmcp/) [Cal MCPOAuth 2.1/DCR](/agentkit/connectors/calmcp/) [Connect to Cal MCP. Manage bookings, event types, schedules, and availability from your AI workflows.](/agentkit/connectors/calmcp/) [Vendor MCP35 tools](/agentkit/connectors/calmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/calendly.svg)](/agentkit/connectors/calendly/) [CalendlyOAuth 2.0](/agentkit/connectors/calendly/) [Connect to Calendly. Access user profile, events, and scheduling workflows.](/agentkit/connectors/calendly/) [scalekit64 tools](/agentkit/connectors/calendly/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/calendly.svg)](/agentkit/connectors/calendlymcp/) [Calendly MCPOAuth 2.1/DCR](/agentkit/connectors/calendlymcp/) [Connect to the Calendly MCP server to manage scheduled events, invitees, event types, and availability directly from your AI workflows.](/agentkit/connectors/calendlymcp/) [Vendor MCP36 tools](/agentkit/connectors/calendlymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/circleback.svg)](/agentkit/connectors/circlebackmcp/) [Circleback MCPOAuth 2.1/DCR](/agentkit/connectors/circlebackmcp/) [Circleback is an AI meeting notes and conversation intelligence platform. The Circleback MCP server provides a standardized interface that allows any...](/agentkit/connectors/circlebackmcp/) [Vendor MCP11 tools](/agentkit/connectors/circlebackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_calendar.svg)](/agentkit/connectors/googlecalendar/) [Google CalendarOAuth 2.0](/agentkit/connectors/googlecalendar/) [Google Calendar is Google's cloud-based calendar service that allows you to manage your events, appointments, and schedules from any computer or device...](/agentkit/connectors/googlecalendar/) [scalekit30 tools](/agentkit/connectors/googlecalendar/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_meet.svg)](/agentkit/connectors/googlemeet/) [Google MeetOAuth 2.0](/agentkit/connectors/googlemeet/) [Connect to Google Meet. Create and manage video meetings with powerful collaboration features](/agentkit/connectors/googlemeet/) [scalekit16 tools](/agentkit/connectors/googlemeet/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/outlook.svg)](/agentkit/connectors/outlook/) [OutlookOAuth 2.0](/agentkit/connectors/outlook/) [Connect to Microsoft Outlook. Manage emails, calendar events, contacts, and tasks](/agentkit/connectors/outlook/) [scalekit126 tools](/agentkit/connectors/outlook/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planningcenter.svg)](/agentkit/connectors/planningcentermcp/) [Planning Center MCPOAuth 2.1/DCR](/agentkit/connectors/planningcentermcp/) [Planning Center is a church management platform with modules for people (contact database), giving, check-ins, services planning, groups, registrations...](/agentkit/connectors/planningcentermcp/) [Vendor MCP64 tools](/agentkit/connectors/planningcentermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/roam.svg)](/agentkit/connectors/roammcp/) [Roam MCPOAuth 2.1/DCR](/agentkit/connectors/roammcp/) [Connect to Roam MCP. Access and manage meetings, transcripts, chat messages, calendar events, and people data across your Roam virtual office workspace.](/agentkit/connectors/roammcp/) [Vendor MCP56 tools](/agentkit/connectors/roammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoom.svg)](/agentkit/connectors/zoom/) [ZoomOAuth 2.0](/agentkit/connectors/zoom/) [Connect to Zoom. Schedule meetings, manage recordings, and handle video conferencing workflows](/agentkit/connectors/zoom/) [scalekit58 tools](/agentkit/connectors/zoom/) ## Collaboration [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asana/) [AsanaOAuth 2.0](/agentkit/connectors/asana/) [Connect to Asana. Manage tasks, projects, teams, and workflow automation](/agentkit/connectors/asana/) [scalekit210 tools](/agentkit/connectors/asana/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/atlassian.svg)](/agentkit/connectors/atlassianmcp/) [Atlassian Rovo MCPOAuth 2.1/DCR](/agentkit/connectors/atlassianmcp/) [Connect to Atlassian Rovo MCP server to manage Jira issues, Confluence pages, and Compass components directly from your AI workflows.](/agentkit/connectors/atlassianmcp/) [Vendor MCP39 tools](/agentkit/connectors/atlassianmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitbucket.svg)](/agentkit/connectors/bitbucket/) [BitbucketOAuth 2.0](/agentkit/connectors/bitbucket/) [Connect to Bitbucket. Manage repositories, pipelines, pull requests, and code collaboration.](/agentkit/connectors/bitbucket/) [scalekit171 tools](/agentkit/connectors/bitbucket/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/canva.svg)](/agentkit/connectors/canva/) [CanvaOAuth 2.0](/agentkit/connectors/canva/) [Connect to Canva's Connect API to manage designs, assets, folders, brand templates, comments, autofills, exports, and analytics on the user's behalf via...](/agentkit/connectors/canva/) [scalekit48 tools](/agentkit/connectors/canva/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/claap.svg)](/agentkit/connectors/claapmcp/) [Claap MCPOAuth 2.1/DCR](/agentkit/connectors/claapmcp/) [Video collaboration platform for recording, sharing, and discussing async video clips — used for meeting recordings, product demos, feedback, and team...](/agentkit/connectors/claapmcp/) [Vendor MCP54 tools](/agentkit/connectors/claapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickup/) [ClickUpOAuth 2.0](/agentkit/connectors/clickup/) [Connect to ClickUp. Manage tasks, projects, workspaces, and team collaboration](/agentkit/connectors/clickup/) [scalekit99 tools](/agentkit/connectors/clickup/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickupmcp/) [ClickUp MCPOAuth 2.1/DCR](/agentkit/connectors/clickupmcp/) [Connect to ClickUp MCP to manage tasks, projects, spaces, and workspaces directly from your AI workflows.](/agentkit/connectors/clickupmcp/) [Vendor MCP57 tools](/agentkit/connectors/clickupmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/confluence.svg)](/agentkit/connectors/confluence/) [ConfluenceOAuth 2.0](/agentkit/connectors/confluence/) [Connect to Confluence. Manage spaces, pages, content, and team collaboration](/agentkit/connectors/confluence/) [scalekit147 tools](/agentkit/connectors/confluence/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/contentful.svg)](/agentkit/connectors/contentfulmcp/) [Contentful MCPOAuth 2.1/DCR](/agentkit/connectors/contentfulmcp/) [Connect to Contentful MCP. Manage spaces, entries, assets, content types, and taxonomies in your Contentful CMS from AI workflows.](/agentkit/connectors/contentfulmcp/) [Vendor MCP70 tools](/agentkit/connectors/contentfulmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/crossbeam.svg)](/agentkit/connectors/crossbeammcp/) [Crossbeam MCPOAuth 2.1/DCR](/agentkit/connectors/crossbeammcp/) [Connect to Crossbeam MCP. Discover partner account overlaps, surface ecosystem activity, get partner and account context, and access co-selling...](/agentkit/connectors/crossbeammcp/) [Vendor MCP9 tools](/agentkit/connectors/crossbeammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/discord.svg)](/agentkit/connectors/discord/) [DiscordOAuth 2.0](/agentkit/connectors/discord/) [Connect to Discord. Read user profile, guilds, roles, manage bots, and perform interactions.](/agentkit/connectors/discord/) [scalekit34 tools](/agentkit/connectors/discord/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/discord.svg)](/agentkit/connectors/discordbot/) [Discord BotAPI Key](/agentkit/connectors/discordbot/) [Connect to Discord as a bot. Manage guilds, channels, members, messages, roles, webhooks, and more using a Discord Bot Token.](/agentkit/connectors/discordbot/) [scalekit221 tools](/agentkit/connectors/discordbot/) [![](https://docs.excalidraw.com/img/logo.svg)](/agentkit/connectors/excalidrawmcp/) [Excalidraw MCPBearer Token](/agentkit/connectors/excalidrawmcp/) [Excalidraw+ is a collaborative whiteboard and diagramming platform. The Excalidraw MCP server lets AI agents manage scenes, collections, workspaces...](/agentkit/connectors/excalidrawmcp/) [Vendor MCP29 tools](/agentkit/connectors/excalidrawmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/felt.svg)](/agentkit/connectors/feltmcp/) [FeltOAuth 2.1/DCR](/agentkit/connectors/feltmcp/) [Connect to Felt, a cloud-native GIS and mapping platform, to manage maps, layers, and geospatial data, query connected spatial databases, and collaborate...](/agentkit/connectors/feltmcp/) [Vendor MCP44 tools](/agentkit/connectors/feltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/figma.svg)](/agentkit/connectors/figma/) [FigmaOAuth 2.0](/agentkit/connectors/figma/) [Connect to Figma to access user files, teams, projects, and design metadata via OAuth 2.0](/agentkit/connectors/figma/) [scalekit54 tools](/agentkit/connectors/figma/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fireflies.svg)](/agentkit/connectors/firefliesmcp/) [Fireflies MCPOAuth 2.1/DCR](/agentkit/connectors/firefliesmcp/) [Connect to Fireflies MCP. Search meeting transcripts, fetch recordings, manage channels, create soundbites, and retrieve analytics from your AI workflows.](/agentkit/connectors/firefliesmcp/) [Vendor MCP20 tools](/agentkit/connectors/firefliesmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/github/) [GithubOAuth 2.0](/agentkit/connectors/github/) [GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code.](/agentkit/connectors/github/) [scalekit217 tools](/agentkit/connectors/github/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/githubpat/) [GitHub (Personal Access Token)Bearer Token](/agentkit/connectors/githubpat/) [GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code. This variant...](/agentkit/connectors/githubpat/) [scalekit217 tools](/agentkit/connectors/githubpat/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/githubmcp/) [GitHub MCPOAuth 2.1](/agentkit/connectors/githubmcp/) [Connect to GitHub MCP. Manage repositories, issues, pull requests, branches, and files directly from your AI workflows.](/agentkit/connectors/githubmcp/) [Vendor MCP44 tools](/agentkit/connectors/githubmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gitlab.svg)](/agentkit/connectors/gitlab/) [GitLabOAuth 2.0](/agentkit/connectors/gitlab/) [Connect to GitLab to manage repositories, issues, merge requests, pipelines, CI/CD, users, groups, and DevOps workflows.](/agentkit/connectors/gitlab/) [scalekit189 tools](/agentkit/connectors/gitlab/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlechat.svg)](/agentkit/connectors/googlechat/) [Google ChatOAuth 2.0](/agentkit/connectors/googlechat/) [Google Chat is Google's messaging and collaboration platform that lets you create and manage spaces, send and search messages, react with emoji, and...](/agentkit/connectors/googlechat/) [scalekit54 tools](/agentkit/connectors/googlechat/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googleclassroom.svg)](/agentkit/connectors/googleclassroom/) [Google ClassroomOAuth 2.0](/agentkit/connectors/googleclassroom/) [Google Classroom is Google's free web-based platform for schools that streamlines creating, distributing, and grading assignments, and simplifies...](/agentkit/connectors/googleclassroom/) [scalekit76 tools](/agentkit/connectors/googleclassroom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grain/) [GrainBearer Token](/agentkit/connectors/grain/) [Grain's REST API for managing meeting recordings, transcripts, webhooks, and workspace data. Search and retrieve recordings and transcripts, upload and...](/agentkit/connectors/grain/) [scalekit19 tools](/agentkit/connectors/grain/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grainmcp/) [Grain MCPOAuth 2.1/DCR](/agentkit/connectors/grainmcp/) [Grain is a meeting recording and intelligence platform. Use this connector to search and retrieve meeting recordings, transcripts, notes, action items...](/agentkit/connectors/grainmcp/) [Vendor MCP41 tools](/agentkit/connectors/grainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/icepanel.png)](/agentkit/connectors/icepanelmcp/) [IcePanel MCPOAuth 2.1/DCR](/agentkit/connectors/icepanelmcp/) [Connect your IcePanel software architecture models to AI agents. Query and update your C4 model landscapes — systems, apps, components, connections, and...](/agentkit/connectors/icepanelmcp/) [Vendor MCP24 tools](/agentkit/connectors/icepanelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lucid.svg)](/agentkit/connectors/lucidmcp/) [Lucid MCPOAuth 2.1/DCR](/agentkit/connectors/lucidmcp/) [Connect to Lucid. Create and edit Lucidchart diagrams, Lucidspark boards, and Lucidscale visualizations from your AI workflows.](/agentkit/connectors/lucidmcp/) [Vendor MCP35 tools](/agentkit/connectors/lucidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miro/) [MiroOAuth 2.0](/agentkit/connectors/miro/) [Miro is a visual collaboration platform for teams. Manage boards, sticky notes, shapes, cards, frames, connectors, images, and tags using the Miro REST...](/agentkit/connectors/miro/) [scalekit115 tools](/agentkit/connectors/miro/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miromcp/) [Miro MCPOAuth 2.1/DCR](/agentkit/connectors/miromcp/) [Connect to Miro MCP to create and manage boards, frames, sticky notes, shapes, diagrams, and comments directly from your AI workflows.](/agentkit/connectors/miromcp/) [Vendor MCP65 tools](/agentkit/connectors/miromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/mondaymcp/) [Monday MCPOAuth 2.1/DCR](/agentkit/connectors/mondaymcp/) [Connect to the monday.com MCP server to manage boards, items, columns, docs, and workflows directly from your AI agents.](/agentkit/connectors/mondaymcp/) [Vendor MCP94 tools](/agentkit/connectors/mondaymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/monday/) [Monday.comOAuth 2.0](/agentkit/connectors/monday/) [Connect to Monday.com. Manage boards, tasks, workflows, teams, and project collaboration](/agentkit/connectors/monday/) [scalekit73 tools](/agentkit/connectors/monday/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nocodb.svg)](/agentkit/connectors/nocodbmcp/) [NocoDB MCPOAuth 2.1/DCR](/agentkit/connectors/nocodbmcp/) [Connect to NocoDB MCP. Create and manage databases, tables, records, views, and fields from your AI workflows.](/agentkit/connectors/nocodbmcp/) [Vendor MCP11 tools](/agentkit/connectors/nocodbmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notion/) [NotionOAuth 2.0](/agentkit/connectors/notion/) [Connect to Notion workspace. Create, edit pages, manage databases, and collaborate on content](/agentkit/connectors/notion/) [scalekit51 tools](/agentkit/connectors/notion/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notionmcp/) [Notion MCPOAuth 2.1/DCR](/agentkit/connectors/notionmcp/) [Connect to Notion MCP. Create and update pages, databases, comments, and views from your AI workflows.](/agentkit/connectors/notionmcp/) [Vendor MCP28 tools](/agentkit/connectors/notionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/otterai.svg)](/agentkit/connectors/otteraimcp/) [OtterAI MCPOAuth 2.1/DCR](/agentkit/connectors/otteraimcp/) [Connect to OtterAI MCP. Search meeting recordings, fetch full transcripts, and retrieve user account info from your AI workflows.](/agentkit/connectors/otteraimcp/) [Vendor MCP3 tools](/agentkit/connectors/otteraimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/roam.svg)](/agentkit/connectors/roammcp/) [Roam MCPOAuth 2.1/DCR](/agentkit/connectors/roammcp/) [Connect to Roam MCP. Access and manage meetings, transcripts, chat messages, calendar events, and people data across your Roam virtual office workspace.](/agentkit/connectors/roammcp/) [Vendor MCP56 tools](/agentkit/connectors/roammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slack/) [SlackOAuth 2.0](/agentkit/connectors/slack/) [Connect to Slack workspace. Send Messages as Bots or on behalf of users](/agentkit/connectors/slack/) [scalekit91 tools](/agentkit/connectors/slack/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slackmcp/) [Slack MCPOAuth 2.1](/agentkit/connectors/slackmcp/) [Connect to Slack MCP. Send and read messages, search channels and users, manage canvases, and react to messages across your Slack workspace.](/agentkit/connectors/slackmcp/) [Vendor MCP19 tools](/agentkit/connectors/slackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slite.svg)](/agentkit/connectors/slitemcp/) [Slite MCPOAuth 2.1/DCR](/agentkit/connectors/slitemcp/) [Connect to Slite MCP. Create and manage notes, channels, collections, and comments in Slite from AI workflows.](/agentkit/connectors/slitemcp/) [Vendor MCP40 tools](/agentkit/connectors/slitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft-teams.svg)](/agentkit/connectors/microsoftteams/) [TeamsOAuth 2.0](/agentkit/connectors/microsoftteams/) [Connect to Microsoft Teams. Manage messages, channels, meetings, and team collaboration](/agentkit/connectors/microsoftteams/) [scalekit82 tools](/agentkit/connectors/microsoftteams/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trello/) [TrelloOAuth 1.0a](/agentkit/connectors/trello/) [Connect to Trello. Manage boards, cards, lists, and team collaboration workflows](/agentkit/connectors/trello/) [scalekit36 tools](/agentkit/connectors/trello/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trellomcp/) [Trello MCPOAuth 2.1/DCR](/agentkit/connectors/trellomcp/) [Connect to Trello's official MCP server to manage boards, cards, lists, and team collaboration workflows directly from your AI workflows.](/agentkit/connectors/trellomcp/) [Vendor MCP15 tools](/agentkit/connectors/trellomcp/) ## Communication [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agentmail.svg)](/agentkit/connectors/agentmailmcp/) [Agentmail MCPOAuth 2.1/DCR](/agentkit/connectors/agentmailmcp/) [Connect to Agentmail MCP. Manage inboxes, send and receive email, handle drafts, threads, and attachments from your AI workflows.](/agentkit/connectors/agentmailmcp/) [Vendor MCP26 tools](/agentkit/connectors/agentmailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brevo.svg)](/agentkit/connectors/brevomcp/) [Brevo MCPOAuth 2.1/DCR](/agentkit/connectors/brevomcp/) [Connect to Brevo MCP. Manage email and SMS campaigns, transactional emails, contacts, lists, automations, and loyalty programs from your AI workflows.](/agentkit/connectors/brevomcp/) [Vendor MCP282 tools](/agentkit/connectors/brevomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/claap.svg)](/agentkit/connectors/claapmcp/) [Claap MCPOAuth 2.1/DCR](/agentkit/connectors/claapmcp/) [Video collaboration platform for recording, sharing, and discussing async video clips — used for meeting recordings, product demos, feedback, and team...](/agentkit/connectors/claapmcp/) [Vendor MCP54 tools](/agentkit/connectors/claapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/close.svg)](/agentkit/connectors/close/) [CloseOAuth 2.0](/agentkit/connectors/close/) [Connect to Close CRM. Manage leads, contacts, opportunities, tasks, activities, and sales workflows](/agentkit/connectors/close/) [scalekit103 tools](/agentkit/connectors/close/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/close.svg)](/agentkit/connectors/closemcp/) [Close MCPOAuth 2.1/DCR](/agentkit/connectors/closemcp/) [Close is a CRM and sales platform. The Close MCP server provides a standardized interface that allows any compatible AI model or agent to access Close CRM...](/agentkit/connectors/closemcp/) [Vendor MCP105 tools](/agentkit/connectors/closemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/discord.svg)](/agentkit/connectors/discord/) [DiscordOAuth 2.0](/agentkit/connectors/discord/) [Connect to Discord. Read user profile, guilds, roles, manage bots, and perform interactions.](/agentkit/connectors/discord/) [scalekit34 tools](/agentkit/connectors/discord/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/discord.svg)](/agentkit/connectors/discordbot/) [Discord BotAPI Key](/agentkit/connectors/discordbot/) [Connect to Discord as a bot. Manage guilds, channels, members, messages, roles, webhooks, and more using a Discord Bot Token.](/agentkit/connectors/discordbot/) [scalekit221 tools](/agentkit/connectors/discordbot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/echtpost.svg)](/agentkit/connectors/echtpostmcp/) [Echtpost MCPOAuth 2.1/DCR](/agentkit/connectors/echtpostmcp/) [Connect to Echtpost MCP. Send physical postcards and letters programmatically via the Echtpost API.](/agentkit/connectors/echtpostmcp/) [Vendor MCP22 tools](/agentkit/connectors/echtpostmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathom/) [FathomAPI Key](/agentkit/connectors/fathom/) [Connect to Fathom AI meeting assistant. Record, transcribe, and summarize meetings with AI-powered insights](/agentkit/connectors/fathom/) [scalekit11 tools](/agentkit/connectors/fathom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathommcp/) [Fathom MCPOAuth 2.1/DCR](/agentkit/connectors/fathommcp/) [Connect to Fathom MCP to access AI meeting notes, summaries, transcripts, and recordings from your AI workflows.](/agentkit/connectors/fathommcp/) [Vendor MCP9 tools](/agentkit/connectors/fathommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/freshdesk.png)](/agentkit/connectors/freshdesk/) [FreshdeskBasic Auth](/agentkit/connectors/freshdesk/) [Connect to Freshdesk. Manage tickets, contacts, companies, and customer support workflows](/agentkit/connectors/freshdesk/) [scalekit34 tools](/agentkit/connectors/freshdesk/) [![](https://app.frontapp.com/v2/favicon192.external-BvfUPbjy.png)](/agentkit/connectors/front/) [FrontOAuth 2.0](/agentkit/connectors/front/) [Connect to Front to manage conversations, messages, comments, drafts, contacts, tags, inboxes, teammates, and channels.](/agentkit/connectors/front/) [scalekit55 tools](/agentkit/connectors/front/) [![](https://app.frontapp.com/favicon.ico)](/agentkit/connectors/frontmcp/) [Front MCPOAuth 2.1](/agentkit/connectors/frontmcp/) [Connect to Front via MCP to manage conversations, comments, drafts, contacts, tags, inboxes, and teammates directly from your AI workflows.](/agentkit/connectors/frontmcp/) [Vendor MCP25 tools](/agentkit/connectors/frontmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gmail.svg)](/agentkit/connectors/gmail/) [GmailOAuth 2.0](/agentkit/connectors/gmail/) [Gmail is Google's cloud based email service that allows you to access your messages from any computer or device with just a web browser.](/agentkit/connectors/gmail/) [scalekit48 tools](/agentkit/connectors/gmail/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_calendar.svg)](/agentkit/connectors/googlecalendar/) [Google CalendarOAuth 2.0](/agentkit/connectors/googlecalendar/) [Google Calendar is Google's cloud-based calendar service that allows you to manage your events, appointments, and schedules from any computer or device...](/agentkit/connectors/googlecalendar/) [scalekit30 tools](/agentkit/connectors/googlecalendar/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlechat.svg)](/agentkit/connectors/googlechat/) [Google ChatOAuth 2.0](/agentkit/connectors/googlechat/) [Google Chat is Google's messaging and collaboration platform that lets you create and manage spaces, send and search messages, react with emoji, and...](/agentkit/connectors/googlechat/) [scalekit54 tools](/agentkit/connectors/googlechat/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_meet.svg)](/agentkit/connectors/googlemeet/) [Google MeetOAuth 2.0](/agentkit/connectors/googlemeet/) [Connect to Google Meet. Create and manage video meetings with powerful collaboration features](/agentkit/connectors/googlemeet/) [scalekit16 tools](/agentkit/connectors/googlemeet/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google.svg)](/agentkit/connectors/googledwd/) [Google Workspace (DWD)Service Account (DWD)](/agentkit/connectors/googledwd/) [Connect to Google Workspace APIs (Gmail, Drive, Docs, Sheets, Slides, Forms) using a GCP service account with Domain-Wide Delegation for server-to-server...](/agentkit/connectors/googledwd/) [scalekit100 tools](/agentkit/connectors/googledwd/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gorgias.svg)](/agentkit/connectors/gorgiasmcp/) [Gorgias MCPOAuth 2.1/DCR](/agentkit/connectors/gorgiasmcp/) [Customer support helpdesk for e-commerce brands. Centralizes conversations from email, chat, social media, and SMS with ticket management and automation.](/agentkit/connectors/gorgiasmcp/) [Vendor MCP82 tools](/agentkit/connectors/gorgiasmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granola/) [GranolaBearer Token](/agentkit/connectors/granola/) [Connect to Granola to access AI-generated meeting notes, summaries, transcripts, and attendee data from your workspace. Granola automatically records and...](/agentkit/connectors/granola/) [scalekit9 tools](/agentkit/connectors/granola/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granolamcp/) [Granola MCPOAuth 2.1/DCR](/agentkit/connectors/granolamcp/) [Connect to Granola MCP using OAuth 2.1 with MCP discovery and dynamic client registration.](/agentkit/connectors/granolamcp/) [Vendor MCP6 tools](/agentkit/connectors/granolamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/intercom.svg)](/agentkit/connectors/intercom/) [IntercomOAuth 2.0](/agentkit/connectors/intercom/) [Connect to Intercom. Send messages, manage conversations, and interact with users and contacts.](/agentkit/connectors/intercom/) [scalekit113 tools](/agentkit/connectors/intercom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkedin.svg)](/agentkit/connectors/linkedin/) [LinkedInOAuth 2.0](/agentkit/connectors/linkedin/) [Connect to LinkedIn to manage posts, ads, organizations, analytics, and professional profiles from your AI workflows.](/agentkit/connectors/linkedin/) [scalekit59 tools](/agentkit/connectors/linkedin/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailerlite.svg)](/agentkit/connectors/mailerlitemcp/) [Mailerlite MCPOAuth 2.1/DCR](/agentkit/connectors/mailerlitemcp/) [Connect to MailerLite MCP. Manage email campaigns, subscribers, groups, automations, and forms from your AI workflows.](/agentkit/connectors/mailerlitemcp/) [Vendor MCP77 tools](/agentkit/connectors/mailerlitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailgun.svg)](/agentkit/connectors/mailgun/) [MailgunAPI Key](/agentkit/connectors/mailgun/) [Connect to Mailgun to send transactional and marketing email, manage domains and DNS/DKIM security, mailing lists, suppressions (bounces, complaints...](/agentkit/connectors/mailgun/) [scalekit259 tools](/agentkit/connectors/mailgun/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailtrap.svg)](/agentkit/connectors/mailtrap/) [MailtrapBearer Token](/agentkit/connectors/mailtrap/) [Mailtrap is an email delivery platform for developers that provides transactional and bulk email sending, email sandbox testing, and deliverability tools....](/agentkit/connectors/mailtrap/) [scalekit92 tools](/agentkit/connectors/mailtrap/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixmax.svg)](/agentkit/connectors/mixmaxmcp/) [Mixmax MCPOAuth 2.1/DCR](/agentkit/connectors/mixmaxmcp/) [Connect to Mixmax MCP. Manage email sequences, templates, contacts, and engagement analytics from your AI workflows.](/agentkit/connectors/mixmaxmcp/) [Vendor MCP3 tools](/agentkit/connectors/mixmaxmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/outlook.svg)](/agentkit/connectors/outlook/) [OutlookOAuth 2.0](/agentkit/connectors/outlook/) [Connect to Microsoft Outlook. Manage emails, calendar events, contacts, and tasks](/agentkit/connectors/outlook/) [scalekit126 tools](/agentkit/connectors/outlook/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postmark.svg)](/agentkit/connectors/postmark/) [PostmarkAPI Key](/agentkit/connectors/postmark/) [Send and track transactional and broadcast email with Postmark. Manage templates, message streams, bounces, suppressions, webhooks, and delivery...](/agentkit/connectors/postmark/) [scalekit59 tools](/agentkit/connectors/postmark/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quo.svg)](/agentkit/connectors/quomcp/) [Quo MCPOAuth 2.1/DCR](/agentkit/connectors/quomcp/) [Connect to Quo MCP. Access call details, summaries, transcripts, and voicemails, send text messages, and create or update contacts from your AI workflows.](/agentkit/connectors/quomcp/) [Vendor MCP15 tools](/agentkit/connectors/quomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/reddit.svg)](/agentkit/connectors/reddit/) [RedditOAuth 2.0](/agentkit/connectors/reddit/) [Connect to Reddit to access user identity, subreddit data, posts, comments, and mod tools.](/agentkit/connectors/reddit/) [scalekit105 tools](/agentkit/connectors/reddit/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resend/) [ResendBearer Token](/agentkit/connectors/resend/) [Resend is an email API platform for developers. Send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts...](/agentkit/connectors/resend/) [scalekit101 tools](/agentkit/connectors/resend/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resendmcp/) [Resend MCPBearer Token](/agentkit/connectors/resendmcp/) [Connect to Resend's official MCP server to send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts, and templates...](/agentkit/connectors/resendmcp/) [Vendor MCP94 tools](/agentkit/connectors/resendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/roam.svg)](/agentkit/connectors/roammcp/) [Roam MCPOAuth 2.1/DCR](/agentkit/connectors/roammcp/) [Connect to Roam MCP. Access and manage meetings, transcripts, chat messages, calendar events, and people data across your Roam virtual office workspace.](/agentkit/connectors/roammcp/) [Vendor MCP56 tools](/agentkit/connectors/roammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/salesloft.svg)](/agentkit/connectors/salesloft/) [SalesloftOAuth 2.0](/agentkit/connectors/salesloft/) [Connect with Salesloft to manage people, cadences, accounts, activities, emails, calls, and notes](/agentkit/connectors/salesloft/) [scalekit56 tools](/agentkit/connectors/salesloft/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sendgrid.svg)](/agentkit/connectors/sendgrid/) [SendGridBearer Token](/agentkit/connectors/sendgrid/) [Connect to Twilio SendGrid to send transactional and marketing email at scale, manage templates, contacts, lists, segments, and single sends, verify...](/agentkit/connectors/sendgrid/) [scalekit391 tools](/agentkit/connectors/sendgrid/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/servicenow.svg)](/agentkit/connectors/servicenow/) [ServiceNowOAuth 2.0](/agentkit/connectors/servicenow/) [Connect to ServiceNow. Manage incidents, service requests, CMDB, and IT service management workflows](/agentkit/connectors/servicenow/) [scalekit112 tools](/agentkit/connectors/servicenow/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slack/) [SlackOAuth 2.0](/agentkit/connectors/slack/) [Connect to Slack workspace. Send Messages as Bots or on behalf of users](/agentkit/connectors/slack/) [scalekit91 tools](/agentkit/connectors/slack/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slackmcp/) [Slack MCPOAuth 2.1](/agentkit/connectors/slackmcp/) [Connect to Slack MCP. Send and read messages, search channels and users, manage canvases, and react to messages across your Slack workspace.](/agentkit/connectors/slackmcp/) [Vendor MCP19 tools](/agentkit/connectors/slackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smtp2go.svg)](/agentkit/connectors/smtp2go/) [SMTP2GOAPI Key](/agentkit/connectors/smtp2go/) [SMTP2GO is a transactional email and SMS delivery platform for developers. Send transactional and bulk email and SMS, manage templates, sender domains...](/agentkit/connectors/smtp2go/) [scalekit74 tools](/agentkit/connectors/smtp2go/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smtp2go.svg)](/agentkit/connectors/smtp2gomcp/) [SMTP2GO MCPAPI Key](/agentkit/connectors/smtp2gomcp/) [SMTP2GO's MCP server exposes its API documentation and a generic request executor - discover SMTP2GO API endpoints (list-endpoints, get-endpoint...](/agentkit/connectors/smtp2gomcp/) [Vendor MCP5 tools](/agentkit/connectors/smtp2gomcp/) [![](https://dac-static.atlassian.com/_static/Statuspage-blue.svg)](/agentkit/connectors/statuspage/) [StatuspageAPI Key](/agentkit/connectors/statuspage/) [Connect to Statuspage. Manage status pages, incidents, components, component groups, subscribers, metrics, and page access permissions.](/agentkit/connectors/statuspage/) [scalekit99 tools](/agentkit/connectors/statuspage/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft-teams.svg)](/agentkit/connectors/microsoftteams/) [TeamsOAuth 2.0](/agentkit/connectors/microsoftteams/) [Connect to Microsoft Teams. Manage messages, channels, meetings, and team collaboration](/agentkit/connectors/microsoftteams/) [scalekit82 tools](/agentkit/connectors/microsoftteams/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/telnyx.svg)](/agentkit/connectors/telnyxmcp/) [Telnyx MCPOAuth 2.1/DCR](/agentkit/connectors/telnyxmcp/) [Telnyx is a communications platform for voice, messaging, and AI. This MCP connector lets AI agents manage phone numbers, send SMS and MMS, place and...](/agentkit/connectors/telnyxmcp/) [Vendor MCP6 tools](/agentkit/connectors/telnyxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/twilio.svg)](/agentkit/connectors/twilio/) [TwilioBasic Auth](/agentkit/connectors/twilio/) [Connect to Twilio to send SMS/MMS messages, make voice calls, verify phone numbers with OTP, manage phone numbers, and access usage records.](/agentkit/connectors/twilio/) [scalekit61 tools](/agentkit/connectors/twilio/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitter/) [Twitter / XBearer Token](/agentkit/connectors/twitter/) [Connect to Twitter. Read and write Tweets, read users, manage follows, bookmarks, etc.](/agentkit/connectors/twitter/) [scalekit104 tools](/agentkit/connectors/twitter/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitterbearer/) [Twitter / XBearer Token](/agentkit/connectors/twitterbearer/) [Connect to Twitter using an App-Only Bearer Token to access public, read-only, and application-level endpoints — search, compliance jobs and streams...](/agentkit/connectors/twitterbearer/) [scalekit44 tools](/agentkit/connectors/twitterbearer/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitteroauth/) [Twitter / XOAuth 2.0](/agentkit/connectors/twitteroauth/) [Connect to Twitter using OAuth 2.0 (Authorization Code with PKCE) to read and write Tweets on behalf of the authenticated user, manage users, follows...](/agentkit/connectors/twitteroauth/) [scalekit92 tools](/agentkit/connectors/twitteroauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vapi.svg)](/agentkit/connectors/vapimcp/) [Vapi MCPBearer Token](/agentkit/connectors/vapimcp/) [Vapi is an AI-powered voice platform for building, testing, and deploying voice AI agents. This MCP connector enables AI agents to manage Vapi assistants...](/agentkit/connectors/vapimcp/) [Vendor MCP13 tools](/agentkit/connectors/vapimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zendesk.svg)](/agentkit/connectors/zendesk/) [ZendeskAPI KEY](/agentkit/connectors/zendesk/) [Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations](/agentkit/connectors/zendesk/) [scalekit137 tools](/agentkit/connectors/zendesk/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zendesk.svg)](/agentkit/connectors/zendeskoauth/) [Zendesk (OAUTH)OAuth 2.0](/agentkit/connectors/zendeskoauth/) [Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations](/agentkit/connectors/zendeskoauth/) [scalekit137 tools](/agentkit/connectors/zendeskoauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoom.svg)](/agentkit/connectors/zoom/) [ZoomOAuth 2.0](/agentkit/connectors/zoom/) [Connect to Zoom. Schedule meetings, manage recordings, and handle video conferencing workflows](/agentkit/connectors/zoom/) [scalekit58 tools](/agentkit/connectors/zoom/) ## CRM & Sales [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/affinity.svg)](/agentkit/connectors/affinity/) [AffinityBearer Token](/agentkit/connectors/affinity/) [Connect to Affinity relationship intelligence CRM to manage deal flow, relationships, pipeline opportunities, and network connections for private capital...](/agentkit/connectors/affinity/) [scalekit49 tools](/agentkit/connectors/affinity/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/ahrefs.svg)](/agentkit/connectors/ahrefsmcp/) [Ahrefs MCPOAuth 2.1/DCR](/agentkit/connectors/ahrefsmcp/) [Connect to Ahrefs MCP to access SEO data including backlinks, keyword research, site audits, rank tracking, and web analytics directly from your AI...](/agentkit/connectors/ahrefsmcp/) [Vendor MCP134 tools](/agentkit/connectors/ahrefsmcp/) [![](https://docs.amplemarket.com/mintlify-assets/_mintlify/favicons/amplemarket-50/mca-0KUOMtPMXsSB/_generated/favicon-dark/favicon-32x32.png)](/agentkit/connectors/amplemarket/) [AmplemarketBearer Token](/agentkit/connectors/amplemarket/) [Connect to Amplemarket, an AI-powered sales engagement platform, to search and enrich B2B leads, manage email/LinkedIn outreach sequences, and score...](/agentkit/connectors/amplemarket/) [scalekit47 tools](/agentkit/connectors/amplemarket/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apollo/) [ApolloOAuth 2.0](/agentkit/connectors/apollo/) [Connect to Apollo.io to search and enrich B2B contacts and accounts, manage CRM contacts, and automate outreach sequences.](/agentkit/connectors/apollo/) [scalekit75 tools](/agentkit/connectors/apollo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apolloapikey/) [Apollo (API Key)API Key](/agentkit/connectors/apolloapikey/) [Connect to Apollo.io using a master API key to search and enrich B2B contacts and accounts, manage CRM records, sequences, tasks, and deals, and access...](/agentkit/connectors/apolloapikey/) [scalekit80 tools](/agentkit/connectors/apolloapikey/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apollomcp/) [Apollo MCPOAuth 2.1/DCR](/agentkit/connectors/apollomcp/) [Connect to Apollo MCP to search B2B contacts, enrich people and organizations, manage CRM records, and enroll prospects in sequences.](/agentkit/connectors/apollomcp/) [Vendor MCP61 tools](/agentkit/connectors/apollomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attention.svg)](/agentkit/connectors/attention/) [AttentionAPI Key](/agentkit/connectors/attention/) [Connect to Attention for AI insights, conversations, teams, and workflows](/agentkit/connectors/attention/) [scalekit28 tools](/agentkit/connectors/attention/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attio.svg)](/agentkit/connectors/attio/) [AttioOAuth 2.0](/agentkit/connectors/attio/) [Connect to Attio CRM to manage contacts, companies, deals, notes, tasks, and lists with a modern relationship management platform.](/agentkit/connectors/attio/) [scalekit109 tools](/agentkit/connectors/attio/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attio.svg)](/agentkit/connectors/attiomcp/) [Attio MCPOAuth 2.1/DCR](/agentkit/connectors/attiomcp/) [Connect to Attio MCP. Access and manage CRM records, lists, notes, tasks, emails, and workspace data across people, companies, and deals.](/agentkit/connectors/attiomcp/) [Vendor MCP38 tools](/agentkit/connectors/attiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitly.svg)](/agentkit/connectors/bitlymcp/) [Bitly MCPOAuth 2.1/DCR](/agentkit/connectors/bitlymcp/) [Connect with Bitly MCP for URL shortening, link analytics, and branded links.](/agentkit/connectors/bitlymcp/) [Vendor MCP79 tools](/agentkit/connectors/bitlymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bonsai.svg)](/agentkit/connectors/bonsaimcp/) [Bonsai MCPOAuth 2.1/DCR](/agentkit/connectors/bonsaimcp/) [Connect to Bonsai, the all-in-one business management platform for freelancers and agencies. Manage projects, tasks, CRM contacts, deals, invoices, and...](/agentkit/connectors/bonsaimcp/) [Vendor MCP34 tools](/agentkit/connectors/bonsaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chilipiper.svg)](/agentkit/connectors/chilipipermcp/) [ChiliPiper MCPBearer Token](/agentkit/connectors/chilipipermcp/) [Connect to ChiliPiper MCP. Schedule meetings, manage routing rules, track distributions, and automate handoffs from your AI agents.](/agentkit/connectors/chilipipermcp/) [Vendor MCP156 tools](/agentkit/connectors/chilipipermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chorus.svg)](/agentkit/connectors/chorus/) [ChorusBasic Auth](/agentkit/connectors/chorus/) [Connect to Chorus.ai to sync calls, transcripts, conversation intelligence, and analytics.](/agentkit/connectors/chorus/) [scalekit9 tools](/agentkit/connectors/chorus/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clari.svg)](/agentkit/connectors/clari_copilot/) [Clari CopilotAPI Key](/agentkit/connectors/clari_copilot/) [Connect to Clari Copilot for sales call transcripts, analytics, call data, and insights.](/agentkit/connectors/clari_copilot/) [scalekitComing soon](/agentkit/connectors/clari_copilot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clarify.svg)](/agentkit/connectors/clarifymcp/) [Clarify MCPOAuth 2.1/DCR](/agentkit/connectors/clarifymcp/) [Connect to Clarify MCP to manage CRM records, leads, campaigns, lists, and analytics directly from your AI workflows.](/agentkit/connectors/clarifymcp/) [Vendor MCP38 tools](/agentkit/connectors/clarifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clay.svg)](/agentkit/connectors/claymcp/) [Clay MCPOAuth 2.1/DCR](/agentkit/connectors/claymcp/) [Clay is a go-to-market (GTM) platform that unifies data sourcing from 150+ providers, AI-powered research agents, and workflow orchestration for sales and...](/agentkit/connectors/claymcp/) [Vendor MCP17 tools](/agentkit/connectors/claymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/close.svg)](/agentkit/connectors/close/) [CloseOAuth 2.0](/agentkit/connectors/close/) [Connect to Close CRM. Manage leads, contacts, opportunities, tasks, activities, and sales workflows](/agentkit/connectors/close/) [scalekit103 tools](/agentkit/connectors/close/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/close.svg)](/agentkit/connectors/closemcp/) [Close MCPOAuth 2.1/DCR](/agentkit/connectors/closemcp/) [Close is a CRM and sales platform. The Close MCP server provides a standardized interface that allows any compatible AI model or agent to access Close CRM...](/agentkit/connectors/closemcp/) [Vendor MCP105 tools](/agentkit/connectors/closemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/commonroom.svg)](/agentkit/connectors/commonroommcp/) [Commonroom MCPOAuth 2.1/DCR](/agentkit/connectors/commonroommcp/) [Connect to Common Room MCP to manage community members, objects, and feedback data directly from your AI workflows.](/agentkit/connectors/commonroommcp/) [Vendor MCP5 tools](/agentkit/connectors/commonroommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/crossbeam.svg)](/agentkit/connectors/crossbeammcp/) [Crossbeam MCPOAuth 2.1/DCR](/agentkit/connectors/crossbeammcp/) [Connect to Crossbeam MCP. Discover partner account overlaps, surface ecosystem activity, get partner and account context, and access co-selling...](/agentkit/connectors/crossbeammcp/) [Vendor MCP9 tools](/agentkit/connectors/crossbeammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/crustdata.svg)](/agentkit/connectors/crustdatamcp/) [Crustdata MCPOAuth 2.1/DCR](/agentkit/connectors/crustdatamcp/) [People and company intelligence platform for candidate sourcing, sales prospecting, and talent intelligence. Provides real-time data on professionals...](/agentkit/connectors/crustdatamcp/) [Vendor MCP68 tools](/agentkit/connectors/crustdatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/customerio.svg)](/agentkit/connectors/customeriomcp/) [Customer.io MCPOAuth 2.1/DCR](/agentkit/connectors/customeriomcp/) [Connect to Customer.io MCP to manage customers, campaigns, and events](/agentkit/connectors/customeriomcp/) [Vendor MCP8 tools](/agentkit/connectors/customeriomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dropcontact.svg)](/agentkit/connectors/dropcontactmcp/) [Dropcontact MCPOAuth 2.1/DCR](/agentkit/connectors/dropcontactmcp/) [B2B contact enrichment and email verification platform that finds, verifies, and enriches professional email addresses and company data.](/agentkit/connectors/dropcontactmcp/) [Vendor MCP6 tools](/agentkit/connectors/dropcontactmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dynamo.svg)](/agentkit/connectors/dynamo/) [Dynamo SoftwareBearer Token](/agentkit/connectors/dynamo/) [Connect to Dynamo Software API to access investment management, CRM, and reporting data.](/agentkit/connectors/dynamo/) [scalekit36 tools](/agentkit/connectors/dynamo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/evertrace.png)](/agentkit/connectors/evertrace/) [Evertrace AIBearer Token](/agentkit/connectors/evertrace/) [Connect to evertrace.ai to search and manage talent signals, saved searches, and lists. Access rich professional profiles with scoring, experiences, and...](/agentkit/connectors/evertrace/) [scalekit26 tools](/agentkit/connectors/evertrace/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/folk.svg)](/agentkit/connectors/folkmcp/) [Folk MCPOAuth 2.1/DCR](/agentkit/connectors/folkmcp/) [Folk is a collaborative CRM that helps teams manage contacts, track relationships, and run outreach — all in one workspace.](/agentkit/connectors/folkmcp/) [Vendor MCP14 tools](/agentkit/connectors/folkmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fullenrich.svg)](/agentkit/connectors/fullenrichmcp/) [Fullenrich MCPOAuth 2.1/DCR](/agentkit/connectors/fullenrichmcp/) [Connect to FullEnrich MCP. Enrich contacts with verified email addresses and phone numbers using waterfall enrichment across multiple data providers.](/agentkit/connectors/fullenrichmcp/) [Vendor MCP13 tools](/agentkit/connectors/fullenrichmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gainsight.svg)](/agentkit/connectors/gainsight/) [GainsightAPI Key](/agentkit/connectors/gainsight/) [Connect to Gainsight Customer Success to manage companies, contacts, calls to action, success plans, timeline activities, and custom objects. Power...](/agentkit/connectors/gainsight/) [scalekit28 tools](/agentkit/connectors/gainsight/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gong/) [GongOAuth 2.0](/agentkit/connectors/gong/) [Connect with Gong to sync calls, transcripts, insights, coaching and CRM activity](/agentkit/connectors/gong/) [scalekit49 tools](/agentkit/connectors/gong/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gongmcp/) [Gong MCPOAuth 2.1](/agentkit/connectors/gongmcp/) [Connect with Gong MCP to access calls, transcripts, insights, coaching, and sales engagement data via the Model Context Protocol](/agentkit/connectors/gongmcp/) [Vendor MCP3 tools](/agentkit/connectors/gongmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_ads.png)](/agentkit/connectors/googleads/) [Google AdsOAuth 2.0](/agentkit/connectors/googleads/) [Connect to Google Ads to manage advertising campaigns, analyze performance metrics, and optimize ad spending across Google's advertising platform](/agentkit/connectors/googleads/) [scalekit35 tools](/agentkit/connectors/googleads/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/heyreach.svg)](/agentkit/connectors/heyreach/) [HeyReachAPI Key](/agentkit/connectors/heyreach/) [Connect to HeyReach to manage LinkedIn outreach campaigns, lead lists, and conversations. List campaigns, retrieve leads, monitor campaign progress, and...](/agentkit/connectors/heyreach/) [scalekit14 tools](/agentkit/connectors/heyreach/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hub_spot.svg)](/agentkit/connectors/hubspot/) [HubSpotOAuth 2.0](/agentkit/connectors/hubspot/) [Connect to HubSpot CRM. Manage contacts, deals, companies, and marketing automation](/agentkit/connectors/hubspot/) [scalekit457 tools](/agentkit/connectors/hubspot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hub_spot.svg)](/agentkit/connectors/hubspotmcp/) [HubSpot MCPOAuth 2.1](/agentkit/connectors/hubspotmcp/) [Connect to HubSpot MCP. Manage CRM contacts, companies, deals, landing pages, campaigns, and analytics from your AI workflows.](/agentkit/connectors/hubspotmcp/) [Vendor MCP22 tools](/agentkit/connectors/hubspotmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jiminny.svg)](/agentkit/connectors/jiminny/) [JiminnyBearer Token](/agentkit/connectors/jiminny/) [Connect with Jiminny to access call recordings, transcripts, coaching insights, and conversation intelligence data.](/agentkit/connectors/jiminny/) [scalekit27 tools](/agentkit/connectors/jiminny/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/klaviyo.svg)](/agentkit/connectors/klaviyomcp/) [Klaviyo MCPOAuth 2.1/DCR](/agentkit/connectors/klaviyomcp/) [Connect to Klaviyo MCP. Report, strategize & create with real-time Klaviyo data](/agentkit/connectors/klaviyomcp/) [Vendor MCP263 tools](/agentkit/connectors/klaviyomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadboxer.svg)](/agentkit/connectors/leadboxermcp/) [LeadBoxer MCPOAuth 2.1/DCR](/agentkit/connectors/leadboxermcp/) [Connect to LeadBoxer MCP to identify anonymous website visitors and enrich them with firmographic data. LeadBoxer is a B2B lead generation and website...](/agentkit/connectors/leadboxermcp/) [Vendor MCP5 tools](/agentkit/connectors/leadboxermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadfeeder.svg)](/agentkit/connectors/leadfeedermcp/) [Leadfeeder MCPOAuth 2.1/DCR](/agentkit/connectors/leadfeedermcp/) [Connect to Leadfeeder's MCP server to identify website visitors, track B2B leads, and surface company-level intent data directly from your AI workflows.](/agentkit/connectors/leadfeedermcp/) [Vendor MCP58 tools](/agentkit/connectors/leadfeedermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadiq.svg)](/agentkit/connectors/leadiq/) [LeadIQAPI Key](/agentkit/connectors/leadiq/) [Connect to LeadIQ to search and enrich B2B contacts and companies with verified emails, direct dials, and mobile numbers. Build prospect lists and power...](/agentkit/connectors/leadiq/) [scalekit14 tools](/agentkit/connectors/leadiq/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadiq.svg)](/agentkit/connectors/leadiqmcp/) [LeadIQ MCPOAuth 2.1/DCR](/agentkit/connectors/leadiqmcp/) [Connect to LeadIQ via MCP to search and enrich B2B contacts and companies. Access real-time prospect data, company intelligence, and email/phone...](/agentkit/connectors/leadiqmcp/) [Vendor MCP16 tools](/agentkit/connectors/leadiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lemlist.svg)](/agentkit/connectors/lemlistmcp/) [Lemlist MCPOAuth 2.1/DCR](/agentkit/connectors/lemlistmcp/) [Connect to Lemlist MCP. Manage outbound sales campaigns, leads, email sequences, and LinkedIn outreach from your AI workflows.](/agentkit/connectors/lemlistmcp/) [Vendor MCP123 tools](/agentkit/connectors/lemlistmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkedin.svg)](/agentkit/connectors/linkedin/) [LinkedInOAuth 2.0](/agentkit/connectors/linkedin/) [Connect to LinkedIn to manage posts, ads, organizations, analytics, and professional profiles from your AI workflows.](/agentkit/connectors/linkedin/) [scalekit59 tools](/agentkit/connectors/linkedin/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lusha.svg)](/agentkit/connectors/lushamcp/) [Lusha MCPAPI Key](/agentkit/connectors/lushamcp/) [Connect to Lusha MCP. Search and enrich B2B contacts and companies, find lookalikes, run prospecting searches, and access intent and activity signals from...](/agentkit/connectors/lushamcp/) [Vendor MCP37 tools](/agentkit/connectors/lushamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixmax.svg)](/agentkit/connectors/mixmaxmcp/) [Mixmax MCPOAuth 2.1/DCR](/agentkit/connectors/mixmaxmcp/) [Connect to Mixmax MCP. Manage email sequences, templates, contacts, and engagement analytics from your AI workflows.](/agentkit/connectors/mixmaxmcp/) [Vendor MCP3 tools](/agentkit/connectors/mixmaxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/momentum..svg)](/agentkit/connectors/momentum/) [MomentumAPI Key](/agentkit/connectors/momentum/) [Connect to Momentum, the AI-powered revenue intelligence platform. Retrieve meetings with attendee and transcript details, ingest and remap meetings, run...](/agentkit/connectors/momentum/) [scalekit8 tools](/agentkit/connectors/momentum/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/outreach.png)](/agentkit/connectors/outreach/) [OutreachOAuth 2.0](/agentkit/connectors/outreach/) [Connect with Outreach to manage prospects, accounts, sequences, emails, calls, and sales engagement workflows.](/agentkit/connectors/outreach/) [scalekit80 tools](/agentkit/connectors/outreach/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pipedrive.svg)](/agentkit/connectors/pipedrive/) [PipedriveOAuth 2.0](/agentkit/connectors/pipedrive/) [Connect to Pipedrive CRM. Manage deals, contacts, organizations, activities, leads, and notes to streamline your sales pipeline.](/agentkit/connectors/pipedrive/) [scalekit105 tools](/agentkit/connectors/pipedrive/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pipedrive.svg)](/agentkit/connectors/pipedrivemcp/) [Pipedrive MCPOAuth 2.1/DCR](/agentkit/connectors/pipedrivemcp/) [Connect to Pipedrive CRM via MCP to manage deals, contacts, organizations, leads, activities, and notes directly from your AI workflows.](/agentkit/connectors/pipedrivemcp/) [Vendor MCP32 tools](/agentkit/connectors/pipedrivemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planningcenter.svg)](/agentkit/connectors/planningcentermcp/) [Planning Center MCPOAuth 2.1/DCR](/agentkit/connectors/planningcentermcp/) [Planning Center is a church management platform with modules for people (contact database), giving, check-ins, services planning, groups, registrations...](/agentkit/connectors/planningcentermcp/) [Vendor MCP64 tools](/agentkit/connectors/planningcentermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quo.svg)](/agentkit/connectors/quomcp/) [Quo MCPOAuth 2.1/DCR](/agentkit/connectors/quomcp/) [Connect to Quo MCP. Access call details, summaries, transcripts, and voicemails, send text messages, and create or update contacts from your AI workflows.](/agentkit/connectors/quomcp/) [Vendor MCP15 tools](/agentkit/connectors/quomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/revealedai.svg)](/agentkit/connectors/revealedaimcp/) [Revealed AI MCPOAuth 2.1/DCR](/agentkit/connectors/revealedaimcp/) [Connect to Revealed AI. Track account signals, buyer personas, and people changes to surface timely outreach actions and account intelligence for B2B...](/agentkit/connectors/revealedaimcp/) [Vendor MCP13 tools](/agentkit/connectors/revealedaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sales_force.svg)](/agentkit/connectors/salesforce/) [SalesforceOAuth 2.0](/agentkit/connectors/salesforce/) [Connect to Salesforce CRM. Manage leads, opportunities, accounts, and customer relationships](/agentkit/connectors/salesforce/) [scalekit74 tools](/agentkit/connectors/salesforce/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/salesloft.svg)](/agentkit/connectors/salesloft/) [SalesloftOAuth 2.0](/agentkit/connectors/salesloft/) [Connect with Salesloft to manage people, cadences, accounts, activities, emails, calls, and notes](/agentkit/connectors/salesloft/) [scalekit56 tools](/agentkit/connectors/salesloft/) [![](https://seismic.com/favicon.ico)](/agentkit/connectors/seismic/) [SeismicOAuth 2.0](/agentkit/connectors/seismic/) [Connect to Seismic to manage sales enablement content — browse and manage teamsites and library content, work with personal workspace files, search...](/agentkit/connectors/seismic/) [scalekit45 tools](/agentkit/connectors/seismic/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/storeleads.svg)](/agentkit/connectors/storeleadsmcp/) [StoreLeads MCPBearer Token](/agentkit/connectors/storeleadsmcp/) [Connect to StoreLeads MCP to discover, search, and analyze e-commerce stores and their technology stack from your AI workflows.](/agentkit/connectors/storeleadsmcp/) [Vendor MCP16 tools](/agentkit/connectors/storeleadsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supermetrics.svg)](/agentkit/connectors/supermetricsmcp/) [Supermetrics MCPOAuth 2.1/DCR](/agentkit/connectors/supermetricsmcp/) [Connect to Supermetrics MCP to query marketing data, discover data sources, manage campaigns, and run analytics across your connected ad and analytics...](/agentkit/connectors/supermetricsmcp/) [Vendor MCP14 tools](/agentkit/connectors/supermetricsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sybill.svg)](/agentkit/connectors/sybilmcp/) [Sybill MCPOAuth 2.1/DCR](/agentkit/connectors/sybilmcp/) [Connect to Sybill. Access AI-generated summaries of sales calls, deals, accounts, and conversations to accelerate B2B revenue workflows.](/agentkit/connectors/sybilmcp/) [Vendor MCP7 tools](/agentkit/connectors/sybilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vibeprospecting.svg)](/agentkit/connectors/vibeprospectingmcp/) [Vibe Prospecting MCPOAuth 2.1/DCR](/agentkit/connectors/vibeprospectingmcp/) [Connect to Vibe Prospecting by Explorium to build B2B lead lists, research companies and prospects, enrich contacts, and personalize outreach from your AI...](/agentkit/connectors/vibeprospectingmcp/) [Vendor MCP14 tools](/agentkit/connectors/vibeprospectingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/weflow.svg)](/agentkit/connectors/weflow/) [WeflowBearer Token](/agentkit/connectors/weflow/) [Connect to Weflow's Public API to read call and meeting recordings and their conversation intelligence data — transcripts, comments, clips, interaction...](/agentkit/connectors/weflow/) [scalekit11 tools](/agentkit/connectors/weflow/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoho_crm.svg)](/agentkit/connectors/zohocrm/) [Zoho CRMOAuth 2.0](/agentkit/connectors/zohocrm/) [Connect to Zoho CRM. Manage leads, contacts, accounts, deals, tasks, and other sales activities.](/agentkit/connectors/zohocrm/) [scalekit89 tools](/agentkit/connectors/zohocrm/) [![]()](/agentkit/connectors/zoomrevenueaccelerator/) [Zoom Revenue AcceleratorOAuth 2.0](/agentkit/connectors/zoomrevenueaccelerator/) [Connect to Zoom Revenue Accelerator (formerly Zoom IQ). Access sales conversation intelligence, deal insights, scorecards, CRM data imports, and team...](/agentkit/connectors/zoomrevenueaccelerator/) [scalekit50 tools](/agentkit/connectors/zoomrevenueaccelerator/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoominfo.svg)](/agentkit/connectors/zoominfo/) [ZoomInfoOAuth 2.0](/agentkit/connectors/zoominfo/) [Connect to ZoomInfo to search and enrich B2B contact and company data, access intent signals, discover technographic insights, and manage GTM Studio...](/agentkit/connectors/zoominfo/) [scalekit97 tools](/agentkit/connectors/zoominfo/) ## Customer Support [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devrev.svg)](/agentkit/connectors/devrevmcp/) [Dev Rev MCPBearer Token](/agentkit/connectors/devrevmcp/) [Connect to DevRev MCP. Manage issues, work items, conversations, and customer data in the DevRev product development platform.](/agentkit/connectors/devrevmcp/) [Vendor MCP13 tools](/agentkit/connectors/devrevmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/freshdesk.png)](/agentkit/connectors/freshdesk/) [FreshdeskBasic Auth](/agentkit/connectors/freshdesk/) [Connect to Freshdesk. Manage tickets, contacts, companies, and customer support workflows](/agentkit/connectors/freshdesk/) [scalekit34 tools](/agentkit/connectors/freshdesk/) [![](https://app.frontapp.com/v2/favicon192.external-BvfUPbjy.png)](/agentkit/connectors/front/) [FrontOAuth 2.0](/agentkit/connectors/front/) [Connect to Front to manage conversations, messages, comments, drafts, contacts, tags, inboxes, teammates, and channels.](/agentkit/connectors/front/) [scalekit55 tools](/agentkit/connectors/front/) [![](https://app.frontapp.com/favicon.ico)](/agentkit/connectors/frontmcp/) [Front MCPOAuth 2.1](/agentkit/connectors/frontmcp/) [Connect to Front via MCP to manage conversations, comments, drafts, contacts, tags, inboxes, and teammates directly from your AI workflows.](/agentkit/connectors/frontmcp/) [Vendor MCP25 tools](/agentkit/connectors/frontmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gainsight.svg)](/agentkit/connectors/gainsight/) [GainsightAPI Key](/agentkit/connectors/gainsight/) [Connect to Gainsight Customer Success to manage companies, contacts, calls to action, success plans, timeline activities, and custom objects. Power...](/agentkit/connectors/gainsight/) [scalekit28 tools](/agentkit/connectors/gainsight/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gorgias.svg)](/agentkit/connectors/gorgiasmcp/) [Gorgias MCPOAuth 2.1/DCR](/agentkit/connectors/gorgiasmcp/) [Customer support helpdesk for e-commerce brands. Centralizes conversations from email, chat, social media, and SMS with ticket management and automation.](/agentkit/connectors/gorgiasmcp/) [Vendor MCP82 tools](/agentkit/connectors/gorgiasmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/intercom.svg)](/agentkit/connectors/intercom/) [IntercomOAuth 2.0](/agentkit/connectors/intercom/) [Connect to Intercom. Send messages, manage conversations, and interact with users and contacts.](/agentkit/connectors/intercom/) [scalekit113 tools](/agentkit/connectors/intercom/) [![](https://wac-cdn.atlassian.com/dam/jcr:be09430e-3f78-4712-a953-ddcbe01ea541/jsd-icon.svg?cdnVersion=3478)](/agentkit/connectors/jiraservicemanagement/) [Jira Service ManagementOAuth 2.0](/agentkit/connectors/jiraservicemanagement/) [Connect to Jira Service Management. Manage customer requests, service desks, organizations, knowledge base articles, SLAs, and queues](/agentkit/connectors/jiraservicemanagement/) [scalekit72 tools](/agentkit/connectors/jiraservicemanagement/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/memberstack.svg)](/agentkit/connectors/memberstackmcp/) [Memberstack MCPOAuth 2.1/DCR](/agentkit/connectors/memberstackmcp/) [Connect to Memberstack MCP. Manage members, plans, form submissions, and permissions for your membership-based application.](/agentkit/connectors/memberstackmcp/) [Vendor MCP69 tools](/agentkit/connectors/memberstackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plain.svg)](/agentkit/connectors/plainmcp/) [Plain MCPOAuth 2.1/DCR](/agentkit/connectors/plainmcp/) [Connect to Plain MCP. Manage customer support threads, labels, tenants, Help Center articles, and thread field schemas directly from your AI workflows.](/agentkit/connectors/plainmcp/) [Vendor MCP63 tools](/agentkit/connectors/plainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/prohostai.svg)](/agentkit/connectors/prohostaimcp/) [ProhostAI MCPOAuth 2.1/DCR](/agentkit/connectors/prohostaimcp/) [ProhostAI is an AI-powered property management platform for Airbnb hosts and property managers, offering AI guest messaging, task/cleaning automation...](/agentkit/connectors/prohostaimcp/) [Vendor MCP268 tools](/agentkit/connectors/prohostaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pylon.svg)](/agentkit/connectors/pylon/) [PylonBearer Token](/agentkit/connectors/pylon/) [Connect to Pylon, the modern customer support platform, to manage tickets, contacts, accounts, tasks, projects, and knowledge base content.](/agentkit/connectors/pylon/) [scalekit134 tools](/agentkit/connectors/pylon/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pylon.svg)](/agentkit/connectors/pylonmcp/) [Pylon MCPOAuth 2.1/DCR](/agentkit/connectors/pylonmcp/) [Connect to Pylon MCP. Manage customer issues, accounts, projects, milestones, and tasks from your AI workflows.](/agentkit/connectors/pylonmcp/) [Vendor MCP31 tools](/agentkit/connectors/pylonmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/servicenow.svg)](/agentkit/connectors/servicenow/) [ServiceNowOAuth 2.0](/agentkit/connectors/servicenow/) [Connect to ServiceNow. Manage incidents, service requests, CMDB, and IT service management workflows](/agentkit/connectors/servicenow/) [scalekit112 tools](/agentkit/connectors/servicenow/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zendesk.svg)](/agentkit/connectors/zendesk/) [ZendeskAPI KEY](/agentkit/connectors/zendesk/) [Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations](/agentkit/connectors/zendesk/) [scalekit137 tools](/agentkit/connectors/zendesk/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zendesk.svg)](/agentkit/connectors/zendeskoauth/) [Zendesk (OAUTH)OAuth 2.0](/agentkit/connectors/zendeskoauth/) [Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations](/agentkit/connectors/zendeskoauth/) [scalekit137 tools](/agentkit/connectors/zendeskoauth/) ## Databases [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtable/) [AirtableOAuth 2.0](/agentkit/connectors/airtable/) [Connect to Airtable. Manage databases, tables, records, and collaborate on structured data](/agentkit/connectors/airtable/) [scalekit26 tools](/agentkit/connectors/airtable/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtablemcp/) [Airtable MCPOAuth 2.1/DCR](/agentkit/connectors/airtablemcp/) [Connect to Airtable MCP. Manage bases, tables, records, views, fields, and automations from your AI workflows.](/agentkit/connectors/airtablemcp/) [Vendor MCP43 tools](/agentkit/connectors/airtablemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/redshift.svg)](/agentkit/connectors/redshift/) [AWS RedshiftTrusted IDP](/agentkit/connectors/redshift/) [Amazon Redshift is a fully managed cloud data warehouse that enables fast, cost-effective analysis of structured and semi-structured data at scale.](/agentkit/connectors/redshift/) [scalekit10 tools](/agentkit/connectors/redshift/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg)](/agentkit/connectors/bigqueryserviceaccount/) [BigQuery (Service Account)Service Account](/agentkit/connectors/bigqueryserviceaccount/) [Connect to Google BigQuery using a GCP service account for server-to-server authentication without user login.](/agentkit/connectors/bigqueryserviceaccount/) [scalekit26 tools](/agentkit/connectors/bigqueryserviceaccount/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickhouse.svg)](/agentkit/connectors/clickhouse/) [Clickhouse MCPOAuth 2.1/DCR](/agentkit/connectors/clickhouse/) [Connect to ClickHouse MCP to query, analyze, and manage your ClickHouse databases directly from your AI workflows.](/agentkit/connectors/clickhouse/) [scalekit17 tools](/agentkit/connectors/clickhouse/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databricks-1.svg)](/agentkit/connectors/databricksworkspace/) [Databricks WorkspaceService Principal (OAuth 2.0)](/agentkit/connectors/databricksworkspace/) [Connect to Databricks Workspace APIs using a Service Principal with OAuth 2.0 client credentials to manage clusters, jobs, notebooks, SQL, and more.](/agentkit/connectors/databricksworkspace/) [scalekit53 tools](/agentkit/connectors/databricksworkspace/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bigquery.svg)](/agentkit/connectors/bigquery/) [Google BigQueryOAuth 2.0](/agentkit/connectors/bigquery/) [BigQuery is Google Cloud’s fully-managed enterprise data warehouse for analytics at scale.](/agentkit/connectors/bigquery/) [scalekit47 tools](/agentkit/connectors/bigquery/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motherduck.svg)](/agentkit/connectors/motherduckmcp/) [MotherDuck MCPOAuth 2.1/DCR](/agentkit/connectors/motherduckmcp/) [Connect to MotherDuck MCP. Query and analyze DuckDB databases, explore schemas, create visualizations, and automate data workflows from your AI workflows.](/agentkit/connectors/motherduckmcp/) [Vendor MCP44 tools](/agentkit/connectors/motherduckmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/neon.svg)](/agentkit/connectors/neonmcp/) [Neon MCPOAuth 2.1/DCR](/agentkit/connectors/neonmcp/) [Connect to Neon MCP. Manage Neon serverless Postgres databases, projects, branches, and queries from your AI workflows.](/agentkit/connectors/neonmcp/) [Vendor MCP35 tools](/agentkit/connectors/neonmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nocodb.svg)](/agentkit/connectors/nocodbmcp/) [NocoDB MCPOAuth 2.1/DCR](/agentkit/connectors/nocodbmcp/) [Connect to NocoDB MCP. Create and manage databases, tables, records, views, and fields from your AI workflows.](/agentkit/connectors/nocodbmcp/) [Vendor MCP11 tools](/agentkit/connectors/nocodbmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planetscale.svg)](/agentkit/connectors/planetscalemcp/) [Planet Scale MCPOAuth 2.1/DCR](/agentkit/connectors/planetscalemcp/) [Connect to PlanetScale MCP. Run SQL queries, inspect database branches and schemas, get query performance insights, and manage organizations and invoices...](/agentkit/connectors/planetscalemcp/) [Vendor MCP16 tools](/agentkit/connectors/planetscalemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/prisma.svg)](/agentkit/connectors/prismamcp/) [Prisma MCPOAuth 2.1/DCR](/agentkit/connectors/prismamcp/) [Connect to Prisma MCP. Manage Prisma Postgres databases, run SQL queries, handle backups, and manage connection strings from your AI workflows.](/agentkit/connectors/prismamcp/) [Vendor MCP19 tools](/agentkit/connectors/prismamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/snowflake.svg)](/agentkit/connectors/snowflake/) [SnowflakeOAuth 2.0](/agentkit/connectors/snowflake/) [Connect to Snowflake to manage and analyze your data warehouse workloads](/agentkit/connectors/snowflake/) [scalekit42 tools](/agentkit/connectors/snowflake/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/snowflake.svg)](/agentkit/connectors/snowflakekeyauth/) [Snowflake Key Pair AuthBearer Token](/agentkit/connectors/snowflakekeyauth/) [Connect to Snowflake via Public Private Key Pair to manage and analyze your data warehouse workloads](/agentkit/connectors/snowflakekeyauth/) [scalekit42 tools](/agentkit/connectors/snowflakekeyauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supabase.svg)](/agentkit/connectors/supabase/) [SupabaseOAuth 2.0](/agentkit/connectors/supabase/) [Connect to the Supabase Management API to manage organizations, projects, database branches, API keys, secrets, custom domains, network restrictions...](/agentkit/connectors/supabase/) [scalekit163 tools](/agentkit/connectors/supabase/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supabase.svg)](/agentkit/connectors/supabasemcp/) [Supabase MCPOAuth 2.1/DCR](/agentkit/connectors/supabasemcp/) [Connect to Supabase MCP. Manage projects, databases, branches, Edge Functions, migrations, and logs directly from your AI workflows.](/agentkit/connectors/supabasemcp/) [Vendor MCP29 tools](/agentkit/connectors/supabasemcp/) ## Design [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biorendermcp.svg)](/agentkit/connectors/biorendermcp/) [Bio Render MCPOAuth 2.1/DCR](/agentkit/connectors/biorendermcp/) [Connect to BioRender MCP. Search BioRender's scientific icon and figure template libraries to build publication-ready biological illustrations.](/agentkit/connectors/biorendermcp/) [Vendor MCP2 tools](/agentkit/connectors/biorendermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brandfetch.svg)](/agentkit/connectors/brandfetchmcp/) [Brandfetch MCPOAuth 2.1/DCR](/agentkit/connectors/brandfetchmcp/) [Connect to Brandfetch's MCP server to search, retrieve, and enrich brand data — logos, colors, fonts, and company details — directly from your AI...](/agentkit/connectors/brandfetchmcp/) [Vendor MCP7 tools](/agentkit/connectors/brandfetchmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/canva.svg)](/agentkit/connectors/canva/) [CanvaOAuth 2.0](/agentkit/connectors/canva/) [Connect to Canva's Connect API to manage designs, assets, folders, brand templates, comments, autofills, exports, and analytics on the user's behalf via...](/agentkit/connectors/canva/) [scalekit48 tools](/agentkit/connectors/canva/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eraser.svg)](/agentkit/connectors/erasermcp/) [Eraser MCPOAuth 2.1/DCR](/agentkit/connectors/erasermcp/) [Connect to Eraser MCP. Create and edit diagrams, flowcharts, and technical documentation using Eraser's AI-powered diagramming tools.](/agentkit/connectors/erasermcp/) [Vendor MCP42 tools](/agentkit/connectors/erasermcp/) [![](https://docs.excalidraw.com/img/logo.svg)](/agentkit/connectors/excalidrawmcp/) [Excalidraw MCPBearer Token](/agentkit/connectors/excalidrawmcp/) [Excalidraw+ is a collaborative whiteboard and diagramming platform. The Excalidraw MCP server lets AI agents manage scenes, collections, workspaces...](/agentkit/connectors/excalidrawmcp/) [Vendor MCP29 tools](/agentkit/connectors/excalidrawmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/figma.svg)](/agentkit/connectors/figma/) [FigmaOAuth 2.0](/agentkit/connectors/figma/) [Connect to Figma to access user files, teams, projects, and design metadata via OAuth 2.0](/agentkit/connectors/figma/) [scalekit54 tools](/agentkit/connectors/figma/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kling.svg)](/agentkit/connectors/klingmcp/) [Kling AI MCPOAuth 2.1/DCR](/agentkit/connectors/klingmcp/) [Kling AI is a video and image generation platform. This MCP connector exposes Kling AI capabilities — including video generation and image generation —...](/agentkit/connectors/klingmcp/) [Vendor MCP10 tools](/agentkit/connectors/klingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lucid.svg)](/agentkit/connectors/lucidmcp/) [Lucid MCPOAuth 2.1/DCR](/agentkit/connectors/lucidmcp/) [Connect to Lucid. Create and edit Lucidchart diagrams, Lucidspark boards, and Lucidscale visualizations from your AI workflows.](/agentkit/connectors/lucidmcp/) [Vendor MCP35 tools](/agentkit/connectors/lucidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/magicpatterns.svg)](/agentkit/connectors/magicpatternsmcp/) [Magic Patterns MCPOAuth 2.1/DCR](/agentkit/connectors/magicpatternsmcp/) [Connect to Magic Patterns, the AI-powered UI design tool. Generate, edit, and manage design components and artifacts from your AI workflows.](/agentkit/connectors/magicpatternsmcp/) [Vendor MCP23 tools](/agentkit/connectors/magicpatternsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miro/) [MiroOAuth 2.0](/agentkit/connectors/miro/) [Miro is a visual collaboration platform for teams. Manage boards, sticky notes, shapes, cards, frames, connectors, images, and tags using the Miro REST...](/agentkit/connectors/miro/) [scalekit115 tools](/agentkit/connectors/miro/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miromcp/) [Miro MCPOAuth 2.1/DCR](/agentkit/connectors/miromcp/) [Connect to Miro MCP to create and manage boards, frames, sticky notes, shapes, diagrams, and comments directly from your AI workflows.](/agentkit/connectors/miromcp/) [Vendor MCP65 tools](/agentkit/connectors/miromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mobbins.svg)](/agentkit/connectors/mobbinmcp/) [Mobbin MCPOAuth 2.1/DCR](/agentkit/connectors/mobbinmcp/) [Connect to Mobbin's MCP server to search real-world UI and UX design references from mobile apps, web apps, and websites using natural language. Returns...](/agentkit/connectors/mobbinmcp/) [Vendor MCP3 tools](/agentkit/connectors/mobbinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/onepage.svg)](/agentkit/connectors/onepagemcp/) [Onepage MCPOAuth 2.1/DCR](/agentkit/connectors/onepagemcp/) [Onepage is a website builder platform. The MCP connector lets Claude create, edit, and manage Onepage websites and pages on behalf of the user.](/agentkit/connectors/onepagemcp/) [Vendor MCP54 tools](/agentkit/connectors/onepagemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/recraft.svg)](/agentkit/connectors/recraftmcp/) [Recraft AI MCPOAuth 2.1/DCR](/agentkit/connectors/recraftmcp/) [Connect to Recraft AI MCP. Generate AI-powered images, vectors, icons, and mockups from your AI agents using Recraft's creative design tools.](/agentkit/connectors/recraftmcp/) [Vendor MCP21 tools](/agentkit/connectors/recraftmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/v0.svg)](/agentkit/connectors/v0mcp/) [v0 MCPBearer Token](/agentkit/connectors/v0mcp/) [Connect to v0 by Vercel to generate and iterate on web app UIs from natural language. Create chats, send follow-up messages, and inspect v0 Platform chats...](/agentkit/connectors/v0mcp/) [Vendor MCP5 tools](/agentkit/connectors/v0mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/webflow.svg)](/agentkit/connectors/webflowmcp/) [Webflow MCPOAuth 2.1/DCR](/agentkit/connectors/webflowmcp/) [Connect to Webflow. Build and manage websites, pages, components, styles, assets, CMS collections, and site settings through the Webflow Designer and Data...](/agentkit/connectors/webflowmcp/) [Vendor MCP40 tools](/agentkit/connectors/webflowmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whimsical.svg)](/agentkit/connectors/whimsicalmcp/) [Whimsical MCPOAuth 2.1/DCR](/agentkit/connectors/whimsicalmcp/) [Connect to Whimsical MCP. Create and edit flowcharts, mind maps, wireframes, and docs, and manage boards, comments, and workspaces from your AI workflows.](/agentkit/connectors/whimsicalmcp/) [Vendor MCP18 tools](/agentkit/connectors/whimsicalmcp/) ## Developer Tools [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airbyte.svg)](/agentkit/connectors/airbytemcp/) [Airbyte MCPOAuth 2.1/DCR](/agentkit/connectors/airbytemcp/) [Connect to Airbyte's MCP server to manage data pipelines, sources, destinations, and connections for your data integration workflows.](/agentkit/connectors/airbytemcp/) [Vendor MCP20 tools](/agentkit/connectors/airbytemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/alphaxiv.svg)](/agentkit/connectors/alphaxivmcp/) [AlphaXiv MCPOAuth 2.1/DCR](/agentkit/connectors/alphaxivmcp/) [Connect to AlphaXiv MCP to search and retrieve arXiv research papers, abstracts, authors, and citations from your AI workflows.](/agentkit/connectors/alphaxivmcp/) [Vendor MCP18 tools](/agentkit/connectors/alphaxivmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anchorbrowser.svg)](/agentkit/connectors/anchorbrowsermcp/) [Anchor Browser MCPOAuth 2.1/DCR](/agentkit/connectors/anchorbrowsermcp/) [Connect to Anchor Browser MCP to run cloud browser automation, control live browser sessions, extract web data, and let AI agents browse and act on the...](/agentkit/connectors/anchorbrowsermcp/) [Vendor MCP25 tools](/agentkit/connectors/anchorbrowsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apify.svg)](/agentkit/connectors/apifymcp/) [Apify MCPBearer Token](/agentkit/connectors/apifymcp/) [Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows.](/agentkit/connectors/apifymcp/) [Vendor MCP11 tools](/agentkit/connectors/apifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/appsignal.svg)](/agentkit/connectors/appsignalmcp/) [AppSignal MCPOAuth 2.1/DCR](/agentkit/connectors/appsignalmcp/) [AppSignal is an application monitoring and performance management platform providing error tracking, performance monitoring, and alerting for Ruby...](/agentkit/connectors/appsignalmcp/) [Vendor MCP25 tools](/agentkit/connectors/appsignalmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/axiom.svg)](/agentkit/connectors/axiommcp/) [Axiom MCPOAuth 2.1/DCR](/agentkit/connectors/axiommcp/) [Axiom is a cloud-native data analytics and observability platform for ingesting, storing, and querying logs, events, traces, and metrics at scale. The MCP...](/agentkit/connectors/axiommcp/) [Vendor MCP26 tools](/agentkit/connectors/axiommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/betterstack.svg)](/agentkit/connectors/betterstackmcp/) [Betterstack MCPOAuth 2.1/DCR](/agentkit/connectors/betterstackmcp/) [Monitor uptime, manage logs, and respond to incidents with Better Stack's observability platform.](/agentkit/connectors/betterstackmcp/) [Vendor MCP107 tools](/agentkit/connectors/betterstackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitbucket.svg)](/agentkit/connectors/bitbucket/) [BitbucketOAuth 2.0](/agentkit/connectors/bitbucket/) [Connect to Bitbucket. Manage repositories, pipelines, pull requests, and code collaboration.](/agentkit/connectors/bitbucket/) [scalekit171 tools](/agentkit/connectors/bitbucket/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bugsnag.svg)](/agentkit/connectors/bugsnagmcp/) [Bugsnag MCPOAuth 2.1/DCR](/agentkit/connectors/bugsnagmcp/) [Connect to Bugsnag MCP. Monitor errors, releases, traces, and span groups across your projects from your AI workflows.](/agentkit/connectors/bugsnagmcp/) [Vendor MCP19 tools](/agentkit/connectors/bugsnagmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/buildkite.svg)](/agentkit/connectors/buildkitemcp/) [Buildkite MCPOAuth 2.1/DCR](/agentkit/connectors/buildkitemcp/) [Connect to Buildkite MCP. Manage CI/CD pipelines, builds, agents, clusters, and test suites from your AI workflows.](/agentkit/connectors/buildkitemcp/) [Vendor MCP51 tools](/agentkit/connectors/buildkitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/builtwith.svg)](/agentkit/connectors/builtwithmcp/) [BuiltWith MCPBearer Token](/agentkit/connectors/builtwithmcp/) [BuiltWith tracks the technology stacks of millions of websites. The BuiltWith MCP server lets AI agents look up a site's technology profile, track...](/agentkit/connectors/builtwithmcp/) [Vendor MCP48 tools](/agentkit/connectors/builtwithmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carbone.svg)](/agentkit/connectors/carboneiomcp/) [Carbone.io MCPBearer Token](/agentkit/connectors/carboneiomcp/) [Connect to Carbone.io MCP. Upload templates, render documents by merging templates with JSON data, convert between 100+ formats, and manage template...](/agentkit/connectors/carboneiomcp/) [Vendor MCP11 tools](/agentkit/connectors/carboneiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickhouse.svg)](/agentkit/connectors/clickhouse/) [Clickhouse MCPOAuth 2.1/DCR](/agentkit/connectors/clickhouse/) [Connect to ClickHouse MCP to query, analyze, and manage your ClickHouse databases directly from your AI workflows.](/agentkit/connectors/clickhouse/) [scalekit17 tools](/agentkit/connectors/clickhouse/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudflare/) [CloudflareOAuth 2.0](/agentkit/connectors/cloudflare/) [Cloudflare is a cloud platform providing DNS management, CDN, security, and networking services. This connector enables automated management of zones, DNS...](/agentkit/connectors/cloudflare/) [scalekit31 tools](/agentkit/connectors/cloudflare/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudfaremcp/) [Cloudflare MCPOAuth 2.1/DCR](/agentkit/connectors/cloudfaremcp/) [Connect to Cloudflare MCP to manage your Cloudflare account — execute API calls, search the OpenAPI spec, and interact with Workers, R2, D1, KV, and all...](/agentkit/connectors/cloudfaremcp/) [Vendor MCP3 tools](/agentkit/connectors/cloudfaremcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudinary.svg)](/agentkit/connectors/cloudinarymcp/) [Cloudinary MCPOAuth 2.1/DCR](/agentkit/connectors/cloudinarymcp/) [Connects AI agents to Cloudinary's asset management platform, enabling upload, search, transformation, and organization of media assets through natural...](/agentkit/connectors/cloudinarymcp/) [Vendor MCP30 tools](/agentkit/connectors/cloudinarymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudpress.svg)](/agentkit/connectors/cloudpressmcp/) [Cloudpress MCPOAuth 2.1/DCR](/agentkit/connectors/cloudpressmcp/) [Cloudpress is a managed WordPress hosting platform built for the AI era. Its MCP server lets AI agents manage sites, domains, DNS, security rules...](/agentkit/connectors/cloudpressmcp/) [Vendor MCP66 tools](/agentkit/connectors/cloudpressmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/context7.svg)](/agentkit/connectors/context7mcp/) [Context7 MCPAPI Key](/agentkit/connectors/context7mcp/) [Connect to Context7 MCP to fetch up-to-date, version-specific library documentation and code examples directly from the source.](/agentkit/connectors/context7mcp/) [Vendor MCP2 tools](/agentkit/connectors/context7mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/datadog.svg)](/agentkit/connectors/datadog/) [DatadogAPI Key](/agentkit/connectors/datadog/) [Connect to Datadog to monitor metrics, logs, traces, dashboards, monitors, incidents, SLOs, synthetics, and security signals across your infrastructure.](/agentkit/connectors/datadog/) [scalekit105 tools](/agentkit/connectors/datadog/) [![](https://deepwiki.com/favicon.ico)](/agentkit/connectors/deepwikimcp/) [DeepWikiNo Auth](/agentkit/connectors/deepwikimcp/) [Connect to DeepWiki MCP to ask questions about and read AI-generated documentation for public GitHub repositories directly from your AI workflows.](/agentkit/connectors/deepwikimcp/) [Vendor MCP3 tools](/agentkit/connectors/deepwikimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devrev.svg)](/agentkit/connectors/devrevmcp/) [Dev Rev MCPBearer Token](/agentkit/connectors/devrevmcp/) [Connect to DevRev MCP. Manage issues, work items, conversations, and customer data in the DevRev product development platform.](/agentkit/connectors/devrevmcp/) [Vendor MCP13 tools](/agentkit/connectors/devrevmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/devin.svg)](/agentkit/connectors/devinmcp/) [Devin MCPBearer Token](/agentkit/connectors/devinmcp/) [Connect to Devin MCP. Create and manage AI coding sessions, interact with Devin agents, manage playbooks and schedules, and browse repository wikis from...](/agentkit/connectors/devinmcp/) [Vendor MCP19 tools](/agentkit/connectors/devinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eraser.svg)](/agentkit/connectors/erasermcp/) [Eraser MCPOAuth 2.1/DCR](/agentkit/connectors/erasermcp/) [Connect to Eraser MCP. Create and edit diagrams, flowcharts, and technical documentation using Eraser's AI-powered diagramming tools.](/agentkit/connectors/erasermcp/) [Vendor MCP42 tools](/agentkit/connectors/erasermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/examcp/) [Exa MCPAPI Key](/agentkit/connectors/examcp/) [Connect to Exa MCP to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, and run...](/agentkit/connectors/examcp/) [Vendor MCP2 tools](/agentkit/connectors/examcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/expo.svg)](/agentkit/connectors/expomcp/) [Expo MCPOAuth 2.1/DCR](/agentkit/connectors/expomcp/) [Expo is a platform for building universal React Native apps; its MCP server exposes developer services including EAS builds, submissions, and project...](/agentkit/connectors/expomcp/) [Vendor MCP24 tools](/agentkit/connectors/expomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/firecrawl.svg)](/agentkit/connectors/firecrawlmcp/) [Firecrawl MCPBearer Token](/agentkit/connectors/firecrawlmcp/) [Connect to Firecrawl MCP. Scrape, crawl, search, extract structured data, and monitor websites using Firecrawl's AI-powered web scraping API.](/agentkit/connectors/firecrawlmcp/) [Vendor MCP26 tools](/agentkit/connectors/firecrawlmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/github/) [GithubOAuth 2.0](/agentkit/connectors/github/) [GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code.](/agentkit/connectors/github/) [scalekit217 tools](/agentkit/connectors/github/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/githubpat/) [GitHub (Personal Access Token)Bearer Token](/agentkit/connectors/githubpat/) [GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code. This variant...](/agentkit/connectors/githubpat/) [scalekit217 tools](/agentkit/connectors/githubpat/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/github.png)](/agentkit/connectors/githubmcp/) [GitHub MCPOAuth 2.1](/agentkit/connectors/githubmcp/) [Connect to GitHub MCP. Manage repositories, issues, pull requests, branches, and files directly from your AI workflows.](/agentkit/connectors/githubmcp/) [Vendor MCP44 tools](/agentkit/connectors/githubmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gitlab.svg)](/agentkit/connectors/gitlab/) [GitLabOAuth 2.0](/agentkit/connectors/gitlab/) [Connect to GitLab to manage repositories, issues, merge requests, pipelines, CI/CD, users, groups, and DevOps workflows.](/agentkit/connectors/gitlab/) [scalekit189 tools](/agentkit/connectors/gitlab/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/globalping.svg)](/agentkit/connectors/globalpingmcp/) [Globalping MCPOAuth 2.1/DCR](/agentkit/connectors/globalpingmcp/) [Globalping is a global network measurement platform for running ping, traceroute, DNS lookup, HTTP, and MTR tests from hundreds of probe locations...](/agentkit/connectors/globalpingmcp/) [Vendor MCP12 tools](/agentkit/connectors/globalpingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gocardless.svg)](/agentkit/connectors/gocardlessmcp/) [GoCardless MCPOAuth 2.1/DCR](/agentkit/connectors/gocardlessmcp/) [Connect to GoCardless MCP. Retrieve and list customers, mandates, payments, payouts, refunds, and subscriptions, and explore integration options from your...](/agentkit/connectors/gocardlessmcp/) [Vendor MCP24 tools](/agentkit/connectors/gocardlessmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/greptile.svg)](/agentkit/connectors/greptilmcp/) [Greptile MCPOAuth 2.1/DCR](/agentkit/connectors/greptilmcp/) [AI-powered code search and understanding API that indexes GitHub and GitLab repositories, enabling natural language queries over codebases.](/agentkit/connectors/greptilmcp/) [Vendor MCP16 tools](/agentkit/connectors/greptilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gtmetrix.svg)](/agentkit/connectors/gtmetrixmcp/) [GTmetrix MCPOAuth 2.1/DCR](/agentkit/connectors/gtmetrixmcp/) [Connect to GTmetrix MCP to analyze web page performance, run speed tests, monitor Core Web Vitals, and get actionable optimization recommendations...](/agentkit/connectors/gtmetrixmcp/) [Vendor MCP10 tools](/agentkit/connectors/gtmetrixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hex.svg)](/agentkit/connectors/hexmcp/) [Hex MCPOAuth 2.1/DCR](/agentkit/connectors/hexmcp/) [Connect to Hex MCP. Create and continue data analysis threads, search projects, and query your data using natural language from your AI workflows.](/agentkit/connectors/hexmcp/) [Vendor MCP5 tools](/agentkit/connectors/hexmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/huggingface.svg)](/agentkit/connectors/huggingfacemcp/) [Hugging face MCPOAuth 2.1/DCR](/agentkit/connectors/huggingfacemcp/) [Connect to Hugging Face MCP. Search and manage models, datasets, spaces, and collections on the Hugging Face Hub.](/agentkit/connectors/huggingfacemcp/) [Vendor MCP11 tools](/agentkit/connectors/huggingfacemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/icepanel.png)](/agentkit/connectors/icepanelmcp/) [IcePanel MCPOAuth 2.1/DCR](/agentkit/connectors/icepanelmcp/) [Connect your IcePanel software architecture models to AI agents. Query and update your C4 model landscapes — systems, apps, components, connections, and...](/agentkit/connectors/icepanelmcp/) [Vendor MCP24 tools](/agentkit/connectors/icepanelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jam.svg)](/agentkit/connectors/jammcp/) [Jam MCPOAuth 2.1/DCR](/agentkit/connectors/jammcp/) [Connect to Jam MCP. Access bug reports, console logs, network requests, user events, and video transcripts from your AI workflows.](/agentkit/connectors/jammcp/) [Vendor MCP15 tools](/agentkit/connectors/jammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jentic.svg)](/agentkit/connectors/jenticmcp/) [Jentic MCPOAuth 2.1/DCR](/agentkit/connectors/jenticmcp/) [Connect to Jentic MCP. Search available API actions, load execution details, manage credentials, and execute API operations from your AI workflows.](/agentkit/connectors/jenticmcp/) [Vendor MCP4 tools](/agentkit/connectors/jenticmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jira.svg)](/agentkit/connectors/jira/) [JiraOAuth 2.0](/agentkit/connectors/jira/) [Connect to Jira. Manage issues, projects, workflows, and agile development processes](/agentkit/connectors/jira/) [scalekit374 tools](/agentkit/connectors/jira/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/latch.svg)](/agentkit/connectors/latchbiomcp/) [Latch Bio MCPOAuth 2.1/DCR](/agentkit/connectors/latchbiomcp/) [Latch Bio is a cloud bioinformatics platform for running computational biology workflows. Its MCP server lets AI agents list and retrieve files, manage...](/agentkit/connectors/latchbiomcp/) [Vendor MCP9 tools](/agentkit/connectors/latchbiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/launchdarkly.svg)](/agentkit/connectors/launchdarklymcp/) [LaunchDarkly MCPOAuth 2.1/DCR](/agentkit/connectors/launchdarklymcp/) [Connect to LaunchDarkly's hosted MCP server to manage feature flags, experiments, and release controls directly from your AI workflows.](/agentkit/connectors/launchdarklymcp/) [Vendor MCP136 tools](/agentkit/connectors/launchdarklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linear.svg)](/agentkit/connectors/linear/) [LinearOAuth 2.0](/agentkit/connectors/linear/) [Connect to Linear. Manage issues, projects, sprints, and development workflows](/agentkit/connectors/linear/) [scalekit62 tools](/agentkit/connectors/linear/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linear.svg)](/agentkit/connectors/linearmcp/) [Linear MCPOAuth 2.1/DCR](/agentkit/connectors/linearmcp/) [Connect to Linear's hosted MCP server to manage issues, projects, cycles, and comments directly from your AI workflows.](/agentkit/connectors/linearmcp/) [Vendor MCP63 tools](/agentkit/connectors/linearmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/logrocket.svg)](/agentkit/connectors/logrocketmcp/) [LogRocket MCPOAuth 2.1/DCR](/agentkit/connectors/logrocketmcp/) [Connect to LogRocket to access session data, query analytics, investigate user-reported issues, and detect regressions directly from your AI workflows.](/agentkit/connectors/logrocketmcp/) [Vendor MCP8 tools](/agentkit/connectors/logrocketmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lokalise.svg)](/agentkit/connectors/lokalise/) [LokaliseAPI Key](/agentkit/connectors/lokalise/) [Connect to Lokalise to manage software and content localization: projects, translation keys, translations, languages, comments, contributors, glossary...](/agentkit/connectors/lokalise/) [scalekit109 tools](/agentkit/connectors/lokalise/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailtrap.svg)](/agentkit/connectors/mailtrap/) [MailtrapBearer Token](/agentkit/connectors/mailtrap/) [Mailtrap is an email delivery platform for developers that provides transactional and bulk email sending, email sandbox testing, and deliverability tools....](/agentkit/connectors/mailtrap/) [scalekit92 tools](/agentkit/connectors/mailtrap/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/make.svg)](/agentkit/connectors/makemcp/) [Make MCPOAuth 2.1/DCR](/agentkit/connectors/makemcp/) [Connect to Make (formerly Integromat). Build, run, and manage automation scenarios, data stores, webhooks, and connections across thousands of apps from...](/agentkit/connectors/makemcp/) [Vendor MCP163 tools](/agentkit/connectors/makemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mintlify.svg)](/agentkit/connectors/mintlifymcp/) [Mintlify MCPOAuth 2.1/DCR](/agentkit/connectors/mintlifymcp/) [Connect to Mintlify MCP. Read and edit documentation pages, manage navigation nodes, search content, and publish changes via pull requests from your AI...](/agentkit/connectors/mintlifymcp/) [Vendor MCP19 tools](/agentkit/connectors/mintlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mux.svg)](/agentkit/connectors/muxmcp/) [Mux MCPOAuth 2.1/DCR](/agentkit/connectors/muxmcp/) [Mux is a video infrastructure platform for developers, providing APIs for video hosting, on-demand streaming, live streaming, and playback with analytics...](/agentkit/connectors/muxmcp/) [Vendor MCP2 tools](/agentkit/connectors/muxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/neon.svg)](/agentkit/connectors/neonmcp/) [Neon MCPOAuth 2.1/DCR](/agentkit/connectors/neonmcp/) [Connect to Neon MCP. Manage Neon serverless Postgres databases, projects, branches, and queries from your AI workflows.](/agentkit/connectors/neonmcp/) [Vendor MCP35 tools](/agentkit/connectors/neonmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/netlify.svg)](/agentkit/connectors/netlifymcp/) [Netlify MCPOAuth 2.1/DCR](/agentkit/connectors/netlifymcp/) [Build, deploy, and manage Netlify projects — sites, functions, environment variables, forms, blobs, and edge functions — from AI agents via the Netlify...](/agentkit/connectors/netlifymcp/) [Vendor MCP9 tools](/agentkit/connectors/netlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pagerduty.svg)](/agentkit/connectors/pagerduty/) [PagerDutyOAuth 2.0](/agentkit/connectors/pagerduty/) [Connect to PagerDuty to manage incidents, services, users, teams, escalation policies, schedules, and on-call rotations.](/agentkit/connectors/pagerduty/) [scalekit71 tools](/agentkit/connectors/pagerduty/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/parallel-ai.svg)](/agentkit/connectors/parallelaitaskmcp/) [Parallel AI Task MCPBearer Token](/agentkit/connectors/parallelaitaskmcp/) [Connect to Parallel AI Task MCP to run deep research tasks and task groups directly from your AI workflows.](/agentkit/connectors/parallelaitaskmcp/) [Vendor MCP4 tools](/agentkit/connectors/parallelaitaskmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pixelbin.svg)](/agentkit/connectors/pixelbinmcp/) [Pixelbin MCPOAuth 2.1/DCR](/agentkit/connectors/pixelbinmcp/) [Image and video transformation, optimization, and management platform.](/agentkit/connectors/pixelbinmcp/) [Vendor MCP7 tools](/agentkit/connectors/pixelbinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planetscale.svg)](/agentkit/connectors/planetscalemcp/) [Planet Scale MCPOAuth 2.1/DCR](/agentkit/connectors/planetscalemcp/) [Connect to PlanetScale MCP. Run SQL queries, inspect database branches and schemas, get query performance insights, and manage organizations and invoices...](/agentkit/connectors/planetscalemcp/) [Vendor MCP16 tools](/agentkit/connectors/planetscalemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postman.svg)](/agentkit/connectors/postmanmcp/) [Postman MCPOAuth 2.1/DCR](/agentkit/connectors/postmanmcp/) [Connect to the Postman MCP server to manage collections, workspaces, environments, and APIs directly from your AI workflows.](/agentkit/connectors/postmanmcp/) [Vendor MCP41 tools](/agentkit/connectors/postmanmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/postmark.svg)](/agentkit/connectors/postmark/) [PostmarkAPI Key](/agentkit/connectors/postmark/) [Send and track transactional and broadcast email with Postmark. Manage templates, message streams, bounces, suppressions, webhooks, and delivery...](/agentkit/connectors/postmark/) [scalekit59 tools](/agentkit/connectors/postmark/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/prisma.svg)](/agentkit/connectors/prismamcp/) [Prisma MCPOAuth 2.1/DCR](/agentkit/connectors/prismamcp/) [Connect to Prisma MCP. Manage Prisma Postgres databases, run SQL queries, handle backups, and manage connection strings from your AI workflows.](/agentkit/connectors/prismamcp/) [Vendor MCP19 tools](/agentkit/connectors/prismamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quicknode.svg)](/agentkit/connectors/quicknodemcp/) [Quicknode MCPOAuth 2.1/DCR](/agentkit/connectors/quicknodemcp/) [Connect to QuickNode MCP. Create and manage blockchain RPC endpoints, configure security rules, set rate limits, and monitor usage and logs from your AI...](/agentkit/connectors/quicknodemcp/) [Vendor MCP19 tools](/agentkit/connectors/quicknodemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/replit.svg)](/agentkit/connectors/replitmcp/) [Replit MCPOAuth 2.1/DCR](/agentkit/connectors/replitmcp/) [Connect to Replit MCP. Create, update, and inspect Replit apps from natural-language prompts, list your apps, and resolve apps by name from your AI...](/agentkit/connectors/replitmcp/) [Vendor MCP8 tools](/agentkit/connectors/replitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resend/) [ResendBearer Token](/agentkit/connectors/resend/) [Resend is an email API platform for developers. Send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts...](/agentkit/connectors/resend/) [scalekit101 tools](/agentkit/connectors/resend/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resendmcp/) [Resend MCPBearer Token](/agentkit/connectors/resendmcp/) [Connect to Resend's official MCP server to send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts, and templates...](/agentkit/connectors/resendmcp/) [Vendor MCP94 tools](/agentkit/connectors/resendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sanity.svg)](/agentkit/connectors/sanitymcp/) [Sanity MCPOAuth 2.1/DCR](/agentkit/connectors/sanitymcp/) [Connect to Sanity. Manage structured content, documents, datasets, schemas, releases, and media assets for headless CMS workflows.](/agentkit/connectors/sanitymcp/) [Vendor MCP45 tools](/agentkit/connectors/sanitymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scrapfly.svg)](/agentkit/connectors/scarpflymcp/) [Scarpfly MCPOAuth 2.1/DCR](/agentkit/connectors/scarpflymcp/) [Connect to Scrapfly MCP. Scrape web pages, take screenshots, and control a cloud browser with anti-bot bypass, JS rendering, and proxy support.](/agentkit/connectors/scarpflymcp/) [Vendor MCP31 tools](/agentkit/connectors/scarpflymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/semaphoreci.svg)](/agentkit/connectors/semaphorecimcp/) [Semaphore CI MCPOAuth 2.1/DCR](/agentkit/connectors/semaphorecimcp/) [Semaphore CI is a fast, cloud-native continuous integration and delivery platform that automates building, testing, and deploying software with flexible...](/agentkit/connectors/semaphorecimcp/) [Vendor MCP18 tools](/agentkit/connectors/semaphorecimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sendgrid.svg)](/agentkit/connectors/sendgrid/) [SendGridBearer Token](/agentkit/connectors/sendgrid/) [Connect to Twilio SendGrid to send transactional and marketing email at scale, manage templates, contacts, lists, segments, and single sends, verify...](/agentkit/connectors/sendgrid/) [scalekit391 tools](/agentkit/connectors/sendgrid/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sentry.svg)](/agentkit/connectors/sentrymcp/) [Sentry MCPOAuth 2.1/DCR](/agentkit/connectors/sentrymcp/) [Connect to Sentry MCP server to monitor errors, investigate issues, manage projects, and analyze performance directly from your AI workflows.](/agentkit/connectors/sentrymcp/) [Vendor MCP9 tools](/agentkit/connectors/sentrymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smtp2go.svg)](/agentkit/connectors/smtp2go/) [SMTP2GOAPI Key](/agentkit/connectors/smtp2go/) [SMTP2GO is a transactional email and SMS delivery platform for developers. Send transactional and bulk email and SMS, manage templates, sender domains...](/agentkit/connectors/smtp2go/) [scalekit74 tools](/agentkit/connectors/smtp2go/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smtp2go.svg)](/agentkit/connectors/smtp2gomcp/) [SMTP2GO MCPAPI Key](/agentkit/connectors/smtp2gomcp/) [SMTP2GO's MCP server exposes its API documentation and a generic request executor - discover SMTP2GO API endpoints (list-endpoints, get-endpoint...](/agentkit/connectors/smtp2gomcp/) [Vendor MCP5 tools](/agentkit/connectors/smtp2gomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sportradar.svg)](/agentkit/connectors/sportradarmcp/) [Sportradar MCPOAuth 2.1/DCR](/agentkit/connectors/sportradarmcp/) [Connect to Sportradar MCP. Browse and search sports data API specs, discover endpoints, check coverage, and access guide pages from your AI workflows.](/agentkit/connectors/sportradarmcp/) [Vendor MCP7 tools](/agentkit/connectors/sportradarmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stackai.svg)](/agentkit/connectors/stackaimcp/) [Stack.ai MCPOAuth 2.1/DCR](/agentkit/connectors/stackaimcp/) [Connect to Stack AI MCP. Build, run, and manage AI workflow projects, search knowledge bases, list integration providers, and inspect execution traces...](/agentkit/connectors/stackaimcp/) [Vendor MCP32 tools](/agentkit/connectors/stackaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/stripe.svg)](/agentkit/connectors/stripe/) [StripeBearer Token](/agentkit/connectors/stripe/) [Connect to Stripe to manage customers, payments, products, subscriptions, invoices, and financial data.](/agentkit/connectors/stripe/) [scalekit178 tools](/agentkit/connectors/stripe/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supabase.svg)](/agentkit/connectors/supabase/) [SupabaseOAuth 2.0](/agentkit/connectors/supabase/) [Connect to the Supabase Management API to manage organizations, projects, database branches, API keys, secrets, custom domains, network restrictions...](/agentkit/connectors/supabase/) [scalekit163 tools](/agentkit/connectors/supabase/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supabase.svg)](/agentkit/connectors/supabasemcp/) [Supabase MCPOAuth 2.1/DCR](/agentkit/connectors/supabasemcp/) [Connect to Supabase MCP. Manage projects, databases, branches, Edge Functions, migrations, and logs directly from your AI workflows.](/agentkit/connectors/supabasemcp/) [Vendor MCP29 tools](/agentkit/connectors/supabasemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/swagger.svg)](/agentkit/connectors/swaggermcp/) [Swagger MCPOAuth 2.1/DCR](/agentkit/connectors/swaggermcp/) [Connect to Swagger MCP. Create and manage APIs, developer portals, and documentation in SwaggerHub from AI workflows.](/agentkit/connectors/swaggermcp/) [Vendor MCP26 tools](/agentkit/connectors/swaggermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tavily.svg)](/agentkit/connectors/tavilymcp/) [Tavily MCPOAuth 2.1/DCR](/agentkit/connectors/tavilymcp/) [Connect to Tavily MCP. Search the web, crawl websites, extract content, map site structure, and run deep research using Tavily's AI-powered search API.](/agentkit/connectors/tavilymcp/) [Vendor MCP5 tools](/agentkit/connectors/tavilymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/testdino.svg)](/agentkit/connectors/testidinomcp/) [Testdino MCPOAuth 2.1/DCR](/agentkit/connectors/testidinomcp/) [TestDino is a Playwright test reporting and analytics platform that centralizes test data, detects flaky tests, and provides AI-powered debugging via MCP...](/agentkit/connectors/testidinomcp/) [Vendor MCP38 tools](/agentkit/connectors/testidinomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tinyfish.svg)](/agentkit/connectors/tinyfishmcp/) [Tinyfish MCPOAuth 2.1/DCR](/agentkit/connectors/tinyfishmcp/) [Connect to Tinyfish MCP. Run browser-based web automations, fetch page content, and search the web using a real cloud Chrome browser.](/agentkit/connectors/tinyfishmcp/) [Vendor MCP19 tools](/agentkit/connectors/tinyfishmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/v0.svg)](/agentkit/connectors/v0mcp/) [v0 MCPBearer Token](/agentkit/connectors/v0mcp/) [Connect to v0 by Vercel to generate and iterate on web app UIs from natural language. Create chats, send follow-up messages, and inspect v0 Platform chats...](/agentkit/connectors/v0mcp/) [Vendor MCP5 tools](/agentkit/connectors/v0mcp/) [![](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/vercel.svg)](/agentkit/connectors/vercel/) [VercelOAuth 2.0](/agentkit/connectors/vercel/) [Connect to Vercel. Access user profile, teams, projects, deployments, and environment settings.](/agentkit/connectors/vercel/) [scalekit83 tools](/agentkit/connectors/vercel/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vercel.svg)](/agentkit/connectors/vercelmcp/) [Vercel MCPOAuth 2.1](/agentkit/connectors/vercelmcp/) [Connect to Vercel MCP to manage deployments, projects, domains, environment variables, and team resources directly from your AI workflows.](/agentkit/connectors/vercelmcp/) [Vendor MCP34 tools](/agentkit/connectors/vercelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/webflow.svg)](/agentkit/connectors/webflowmcp/) [Webflow MCPOAuth 2.1/DCR](/agentkit/connectors/webflowmcp/) [Connect to Webflow. Build and manage websites, pages, components, styles, assets, CMS collections, and site settings through the Webflow Designer and Data...](/agentkit/connectors/webflowmcp/) [Vendor MCP40 tools](/agentkit/connectors/webflowmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whop.svg)](/agentkit/connectors/whopmcp/) [Whop MCPOAuth 2.1/DCR](/agentkit/connectors/whopmcp/) [Whop is a platform for selling digital products, memberships, and communities.](/agentkit/connectors/whopmcp/) [Vendor MCP4 tools](/agentkit/connectors/whopmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wix.svg)](/agentkit/connectors/wixmcp/) [Wix MCPOAuth 2.1/DCR](/agentkit/connectors/wixmcp/) [Connect to Wix MCP. Build and manage Wix sites, call REST APIs, search documentation, upload media, and suggest domains from your AI workflows.](/agentkit/connectors/wixmcp/) [Vendor MCP26 tools](/agentkit/connectors/wixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zapier.svg)](/agentkit/connectors/zapiermcp/) [Zapier MCPOAuth 2.1/DCR](/agentkit/connectors/zapiermcp/) [Connect to Zapier MCP to automate workflows and integrate with thousands of apps directly from your AI agent.](/agentkit/connectors/zapiermcp/) [Vendor MCP17 tools](/agentkit/connectors/zapiermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zenrows.svg)](/agentkit/connectors/zenrowsmcp/) [ZenRows MCPOAuth 2.1/DCR](/agentkit/connectors/zenrowsmcp/) [Connect to ZenRows MCP. Scrape any webpage with anti-bot bypass, render JavaScript-heavy sites, and automate browsers through ZenRows' cloud...](/agentkit/connectors/zenrowsmcp/) [Vendor MCP43 tools](/agentkit/connectors/zenrowsmcp/) ## Files & Documents [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/affinda.svg)](/agentkit/connectors/affindamcp/) [Affinda MCPOAuth 2.1/DCR](/agentkit/connectors/affindamcp/) [AI-powered document processing platform that extracts, validates, and integrates structured data from invoices, resumes, contracts, and custom document...](/agentkit/connectors/affindamcp/) [Vendor MCP85 tools](/agentkit/connectors/affindamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airparser.svg)](/agentkit/connectors/airparsermcp/) [Airparser MCPOAuth 2.1/DCR](/agentkit/connectors/airparsermcp/) [AI-powered document parser that extracts structured data from PDFs, emails, and other documents.](/agentkit/connectors/airparsermcp/) [Vendor MCP17 tools](/agentkit/connectors/airparsermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg)](/agentkit/connectors/box/) [BoxOAuth 2.0](/agentkit/connectors/box/) [Box is a cloud content management platform. Manage files, folders, users, groups, collaborations, tasks, comments, webhooks, search, and more using the...](/agentkit/connectors/box/) [scalekit102 tools](/agentkit/connectors/box/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg)](/agentkit/connectors/boxmcp/) [Box MCPOAuth 2.1](/agentkit/connectors/boxmcp/) [Connect to Box via MCP to manage files, folders, collaborations, users, groups, tasks, comments, and search content directly from your AI workflows.](/agentkit/connectors/boxmcp/) [Vendor MCP44 tools](/agentkit/connectors/boxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carbone.svg)](/agentkit/connectors/carboneiomcp/) [Carbone.io MCPBearer Token](/agentkit/connectors/carboneiomcp/) [Connect to Carbone.io MCP. Upload templates, render documents by merging templates with JSON data, convert between 100+ formats, and manage template...](/agentkit/connectors/carboneiomcp/) [Vendor MCP11 tools](/agentkit/connectors/carboneiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/confluence.svg)](/agentkit/connectors/confluence/) [ConfluenceOAuth 2.0](/agentkit/connectors/confluence/) [Connect to Confluence. Manage spaces, pages, content, and team collaboration](/agentkit/connectors/confluence/) [scalekit147 tools](/agentkit/connectors/confluence/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/contentful.svg)](/agentkit/connectors/contentfulmcp/) [Contentful MCPOAuth 2.1/DCR](/agentkit/connectors/contentfulmcp/) [Connect to Contentful MCP. Manage spaces, entries, assets, content types, and taxonomies in your Contentful CMS from AI workflows.](/agentkit/connectors/contentfulmcp/) [Vendor MCP70 tools](/agentkit/connectors/contentfulmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/conversiontools.svg)](/agentkit/connectors/conversiontoolsmcp/) [Conversion Tools MCPOAuth 2.1/DCR](/agentkit/connectors/conversiontoolsmcp/) [Connect to Conversion Tools MCP. Convert files between 140+ formats including documents, images, audio, video, and data files from your AI workflows.](/agentkit/connectors/conversiontoolsmcp/) [Vendor MCP23 tools](/agentkit/connectors/conversiontoolsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/convertapi.svg)](/agentkit/connectors/convertapimcp/) [ConvertAPI MCPOAuth 2.1/DCR](/agentkit/connectors/convertapimcp/) [Connect to ConvertAPI MCP. Convert, merge, split, and transform files across 200+ formats including PDF, Word, Excel, images, and more.](/agentkit/connectors/convertapimcp/) [Vendor MCP5 tools](/agentkit/connectors/convertapimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/docsautomator.svg)](/agentkit/connectors/docsautomatormcp/) [Docsautomator MCPOAuth 2.1/DCR](/agentkit/connectors/docsautomatormcp/) [Connect to DocsAutomator MCP. Generate documents and PDFs from templates using your data, automating document creation workflows.](/agentkit/connectors/docsautomatormcp/) [Vendor MCP20 tools](/agentkit/connectors/docsautomatormcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/drop_box.svg)](/agentkit/connectors/dropbox/) [DropboxOAuth 2.0](/agentkit/connectors/dropbox/) [Connect to Dropbox. Manage files, folders, sharing, and cloud storage workflows](/agentkit/connectors/dropbox/) [scalekit53 tools](/agentkit/connectors/dropbox/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/drop_box.svg)](/agentkit/connectors/dropboxmcp/) [Dropbox MCPOAuth 2.1](/agentkit/connectors/dropboxmcp/) [Connect to Dropbox. Manage files and folders, create shared links, search content, and handle file requests from your AI workflows.](/agentkit/connectors/dropboxmcp/) [Vendor MCP25 tools](/agentkit/connectors/dropboxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_docs.svg)](/agentkit/connectors/googledocs/) [Google DocsOAuth 2.0](/agentkit/connectors/googledocs/) [Connect to Google Docs. Create, edit, and collaborate on documents](/agentkit/connectors/googledocs/) [scalekit47 tools](/agentkit/connectors/googledocs/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_drive.svg)](/agentkit/connectors/googledrive/) [Google DriveOAuth 2.0](/agentkit/connectors/googledrive/) [Connect to Google Drive. Manage files, folders, and sharing permissions](/agentkit/connectors/googledrive/) [scalekit47 tools](/agentkit/connectors/googledrive/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_forms.svg)](/agentkit/connectors/googleforms/) [Google FormsOAuth 2.0](/agentkit/connectors/googleforms/) [Connect to Google Forms. Create, view, and manage forms and responses securely](/agentkit/connectors/googleforms/) [scalekit10 tools](/agentkit/connectors/googleforms/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlephotos.svg)](/agentkit/connectors/googlephotos/) [Google PhotosOAuth 2.0](/agentkit/connectors/googlephotos/) [Google Photos is Google's photo and video storage service for uploading, organizing into albums, and managing media created by your app.](/agentkit/connectors/googlephotos/) [scalekit17 tools](/agentkit/connectors/googlephotos/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_sheets.svg)](/agentkit/connectors/googlesheets/) [Google SheetsOAuth 2.0](/agentkit/connectors/googlesheets/) [Connect to Google Sheets. Create, edit, and analyze spreadsheets with powerful data management capabilities](/agentkit/connectors/googlesheets/) [scalekit48 tools](/agentkit/connectors/googlesheets/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_slides.svg)](/agentkit/connectors/googleslides/) [Google SlidesOAuth 2.0](/agentkit/connectors/googleslides/) [Connect to Google Slides to create, read, and modify presentations programmatically.](/agentkit/connectors/googleslides/) [scalekit5 tools](/agentkit/connectors/googleslides/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lokalise.svg)](/agentkit/connectors/lokalise/) [LokaliseAPI Key](/agentkit/connectors/lokalise/) [Connect to Lokalise to manage software and content localization: projects, translation keys, translations, languages, comments, contributors, glossary...](/agentkit/connectors/lokalise/) [scalekit109 tools](/agentkit/connectors/lokalise/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/excel.svg)](/agentkit/connectors/microsoftexcel/) [Microsoft ExcelOAuth 2.0](/agentkit/connectors/microsoftexcel/) [Connect to Microsoft Excel. Access, read, and modify spreadsheets stored in OneDrive or SharePoint through Microsoft Graph API.](/agentkit/connectors/microsoftexcel/) [scalekit47 tools](/agentkit/connectors/microsoftexcel/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/word.svg)](/agentkit/connectors/microsoftword/) [Microsoft WordOAuth 2.0](/agentkit/connectors/microsoftword/) [Connect to Microsoft Word. Authenticate with your Microsoft account to create, read, and edit Word documents stored in OneDrive or SharePoint through...](/agentkit/connectors/microsoftword/) [scalekit10 tools](/agentkit/connectors/microsoftword/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notion/) [NotionOAuth 2.0](/agentkit/connectors/notion/) [Connect to Notion workspace. Create, edit pages, manage databases, and collaborate on content](/agentkit/connectors/notion/) [scalekit51 tools](/agentkit/connectors/notion/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/onedrive.svg)](/agentkit/connectors/onedrive/) [OneDriveOAuth 2.0](/agentkit/connectors/onedrive/) [Connect to OneDrive. Manage files, folders, and cloud storage with Microsoft OneDrive](/agentkit/connectors/onedrive/) [scalekit46 tools](/agentkit/connectors/onedrive/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/onenote.svg)](/agentkit/connectors/onenote/) [OneNoteOAuth 2.0](/agentkit/connectors/onenote/) [Connect to Microsoft OneNote. Access, create, and manage notebooks, sections, and pages stored in OneDrive or SharePoint through Microsoft Graph API.](/agentkit/connectors/onenote/) [scalekit13 tools](/agentkit/connectors/onenote/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pandadoc.svg)](/agentkit/connectors/pandadocmcp/) [Pandadoc MCPOAuth 2.1/DCR](/agentkit/connectors/pandadocmcp/) [Connect to PandaDoc MCP. Create, send, and manage documents, templates, and e-signatures directly from your AI workflows.](/agentkit/connectors/pandadocmcp/) [Vendor MCP22 tools](/agentkit/connectors/pandadocmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sanity.svg)](/agentkit/connectors/sanitymcp/) [Sanity MCPOAuth 2.1/DCR](/agentkit/connectors/sanitymcp/) [Connect to Sanity. Manage structured content, documents, datasets, schemas, releases, and media assets for headless CMS workflows.](/agentkit/connectors/sanitymcp/) [Vendor MCP45 tools](/agentkit/connectors/sanitymcp/) [![](https://seismic.com/favicon.ico)](/agentkit/connectors/seismic/) [SeismicOAuth 2.0](/agentkit/connectors/seismic/) [Connect to Seismic to manage sales enablement content — browse and manage teamsites and library content, work with personal workspace files, search...](/agentkit/connectors/seismic/) [scalekit45 tools](/agentkit/connectors/seismic/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/send.svg)](/agentkit/connectors/sendmcp/) [Send MCPOAuth 2.1/DCR](/agentkit/connectors/sendmcp/) [Connect to Send to create, edit, and share Claude-generated documents as polished web pages with engagement tracking, custom domains, and team asset...](/agentkit/connectors/sendmcp/) [Vendor MCP12 tools](/agentkit/connectors/sendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sharepoint.svg)](/agentkit/connectors/sharepoint/) [SharePointOAuth 2.0](/agentkit/connectors/sharepoint/) [Connect to SharePoint. Manage sites, documents, lists, and collaborative content](/agentkit/connectors/sharepoint/) [scalekit52 tools](/agentkit/connectors/sharepoint/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/signwell.svg)](/agentkit/connectors/signwell/) [SignWellAPI Key](/agentkit/connectors/signwell/) [SignWell is an e-signature platform for sending, signing, and managing documents. Connect to create and send documents for signature, manage templates...](/agentkit/connectors/signwell/) [scalekit26 tools](/agentkit/connectors/signwell/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slite.svg)](/agentkit/connectors/slitemcp/) [Slite MCPOAuth 2.1/DCR](/agentkit/connectors/slitemcp/) [Connect to Slite MCP. Create and manage notes, channels, collections, and comments in Slite from AI workflows.](/agentkit/connectors/slitemcp/) [Vendor MCP40 tools](/agentkit/connectors/slitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synapse.svg)](/agentkit/connectors/synapsemcp/) [Synapse MCPOAuth 2.1/DCR](/agentkit/connectors/synapsemcp/) [Connect to the Synapse MCP server (Sage Bionetworks) to explore Synapse entities, annotations, provenance, and project structure, and to search...](/agentkit/connectors/synapsemcp/) [Vendor MCP48 tools](/agentkit/connectors/synapsemcp/) ## Finance [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/coinmarketcap.svg)](/agentkit/connectors/coinmarketcapmcp/) [CoinMarketCap MCPOAuth 2.1/DCR](/agentkit/connectors/coinmarketcapmcp/) [Connect to CoinMarketCap MCP. Access real-time crypto quotes, market metrics, technical analysis, trending narratives, and news from your AI workflows.](/agentkit/connectors/coinmarketcapmcp/) [Vendor MCP14 tools](/agentkit/connectors/coinmarketcapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mtnewswires.svg)](/agentkit/connectors/mtnewswiresmcp/) [MT Newswires MCPOAuth 2.1/DCR](/agentkit/connectors/mtnewswiresmcp/) [Connect to the MT Newswires MCP server on viaNexus to search and retrieve real-time, low-latency financial news across equities, fixed income...](/agentkit/connectors/mtnewswiresmcp/) [Vendor MCP6 tools](/agentkit/connectors/mtnewswiresmcp/) ## Healthcare [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/customsmartfhir.png)](/agentkit/connectors/customsmartfhir/) [SMART App on FHIRSMART On FHIR](/agentkit/connectors/customsmartfhir/) [SMART App on FHIR is a healthcare interoperability provider that enables secure access to electronic health records and clinical data using the SMART on...](/agentkit/connectors/customsmartfhir/) [scalekit81 tools](/agentkit/connectors/customsmartfhir/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/advancedmd.png)](/agentkit/connectors/advancedmd/) [AdvancedMDSMART On FHIR](/agentkit/connectors/advancedmd/) [AdvancedMD is a cloud-based medical practice management and electronic health record (EHR) platform. This connector uses the SMART on FHIR authorization...](/agentkit/connectors/advancedmd/) [scalekit89 tools](/agentkit/connectors/advancedmd/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scite.svg)](/agentkit/connectors/scitemcp/) [Scite MCPOAuth 2.1/DCR](/agentkit/connectors/scitemcp/) [Connect to Scite's MCP server to search scientific literature, patents, clinical trials, grants, and FDA drug/device safety data, and manage citation...](/agentkit/connectors/scitemcp/) [Vendor MCP25 tools](/agentkit/connectors/scitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synapse.svg)](/agentkit/connectors/synapsemcp/) [Synapse MCPOAuth 2.1/DCR](/agentkit/connectors/synapsemcp/) [Connect to the Synapse MCP server (Sage Bionetworks) to explore Synapse entities, annotations, provenance, and project structure, and to search...](/agentkit/connectors/synapsemcp/) [Vendor MCP48 tools](/agentkit/connectors/synapsemcp/) ## Marketing [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adobe.svg)](/agentkit/connectors/adobemarketingagentmcp/) [Adobe Marketing Agent MCPOAuth 2.1/DCR](/agentkit/connectors/adobemarketingagentmcp/) [Connect to Adobe Marketing Cloud. Manage campaigns, analytics, and journeys using a natural-language AI assistant.](/agentkit/connectors/adobemarketingagentmcp/) [Vendor MCP12 tools](/agentkit/connectors/adobemarketingagentmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/adzviser.svg)](/agentkit/connectors/adzvisermcp/) [Adzviser MCPOAuth 2.1/DCR](/agentkit/connectors/adzvisermcp/) [Connect to Adzviser MCP to query real-time marketing analytics across 46+ platforms - Google Ads, Facebook Ads, GA4, TikTok, LinkedIn, and more - from a...](/agentkit/connectors/adzvisermcp/) [Vendor MCP58 tools](/agentkit/connectors/adzvisermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agencyanalytics.svg)](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics MCPOAuth 2.1/DCR](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics is a marketing reporting platform that enables digital agencies to monitor SEO, PPC, social media, and other channel performance in...](/agentkit/connectors/agencyanalyticsmcp/) [Vendor MCP35 tools](/agentkit/connectors/agencyanalyticsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/ahrefs.svg)](/agentkit/connectors/ahrefsmcp/) [Ahrefs MCPOAuth 2.1/DCR](/agentkit/connectors/ahrefsmcp/) [Connect to Ahrefs MCP to access SEO data including backlinks, keyword research, site audits, rank tracking, and web analytics directly from your AI...](/agentkit/connectors/ahrefsmcp/) [Vendor MCP134 tools](/agentkit/connectors/ahrefsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airops.svg)](/agentkit/connectors/airopsmcp/) [Airops MCPAPI Key](/agentkit/connectors/airopsmcp/) [Connect to AirOps MCP. Manage brand kits, run AI-powered analytics, track AEO citations, and automate content workflows from your AI agents.](/agentkit/connectors/airopsmcp/) [Vendor MCP91 tools](/agentkit/connectors/airopsmcp/) [![](https://docs.amplemarket.com/mintlify-assets/_mintlify/favicons/amplemarket-50/mca-0KUOMtPMXsSB/_generated/favicon-dark/favicon-32x32.png)](/agentkit/connectors/amplemarket/) [AmplemarketBearer Token](/agentkit/connectors/amplemarket/) [Connect to Amplemarket, an AI-powered sales engagement platform, to search and enrich B2B leads, manage email/LinkedIn outreach sequences, and score...](/agentkit/connectors/amplemarket/) [scalekit47 tools](/agentkit/connectors/amplemarket/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/apollo.svg)](/agentkit/connectors/apollomcp/) [Apollo MCPOAuth 2.1/DCR](/agentkit/connectors/apollomcp/) [Connect to Apollo MCP to search B2B contacts, enrich people and organizations, manage CRM records, and enroll prospects in sequences.](/agentkit/connectors/apollomcp/) [Vendor MCP61 tools](/agentkit/connectors/apollomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bitly.svg)](/agentkit/connectors/bitlymcp/) [Bitly MCPOAuth 2.1/DCR](/agentkit/connectors/bitlymcp/) [Connect with Bitly MCP for URL shortening, link analytics, and branded links.](/agentkit/connectors/bitlymcp/) [Vendor MCP79 tools](/agentkit/connectors/bitlymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brevo.svg)](/agentkit/connectors/brevomcp/) [Brevo MCPOAuth 2.1/DCR](/agentkit/connectors/brevomcp/) [Connect to Brevo MCP. Manage email and SMS campaigns, transactional emails, contacts, lists, automations, and loyalty programs from your AI workflows.](/agentkit/connectors/brevomcp/) [Vendor MCP282 tools](/agentkit/connectors/brevomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/builtwith.svg)](/agentkit/connectors/builtwithmcp/) [BuiltWith MCPBearer Token](/agentkit/connectors/builtwithmcp/) [BuiltWith tracks the technology stacks of millions of websites. The BuiltWith MCP server lets AI agents look up a site's technology profile, track...](/agentkit/connectors/builtwithmcp/) [Vendor MCP48 tools](/agentkit/connectors/builtwithmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clay.svg)](/agentkit/connectors/claymcp/) [Clay MCPOAuth 2.1/DCR](/agentkit/connectors/claymcp/) [Clay is a go-to-market (GTM) platform that unifies data sourcing from 150+ providers, AI-powered research agents, and workflow orchestration for sales and...](/agentkit/connectors/claymcp/) [Vendor MCP17 tools](/agentkit/connectors/claymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/commonroom.svg)](/agentkit/connectors/commonroommcp/) [Commonroom MCPOAuth 2.1/DCR](/agentkit/connectors/commonroommcp/) [Connect to Common Room MCP to manage community members, objects, and feedback data directly from your AI workflows.](/agentkit/connectors/commonroommcp/) [Vendor MCP5 tools](/agentkit/connectors/commonroommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/customerio.svg)](/agentkit/connectors/customeriomcp/) [Customer.io MCPOAuth 2.1/DCR](/agentkit/connectors/customeriomcp/) [Connect to Customer.io MCP to manage customers, campaigns, and events](/agentkit/connectors/customeriomcp/) [Vendor MCP8 tools](/agentkit/connectors/customeriomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dataforseo.svg)](/agentkit/connectors/dataforseomcp/) [Dataforseo MCPOAuth 2.1/DCR](/agentkit/connectors/dataforseomcp/) [Connect to DataForSEO. Access real-time SEO data including SERP results, keyword analytics, backlinks analysis, domain technologies, and AI visibility...](/agentkit/connectors/dataforseomcp/) [Vendor MCP90 tools](/agentkit/connectors/dataforseomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dropcontact.svg)](/agentkit/connectors/dropcontactmcp/) [Dropcontact MCPOAuth 2.1/DCR](/agentkit/connectors/dropcontactmcp/) [B2B contact enrichment and email verification platform that finds, verifies, and enriches professional email addresses and company data.](/agentkit/connectors/dropcontactmcp/) [Vendor MCP6 tools](/agentkit/connectors/dropcontactmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eden.svg)](/agentkit/connectors/edenmcp/) [Eden MCPOAuth 2.1/DCR](/agentkit/connectors/edenmcp/) [Eden is an AI-powered content creation platform that discovers viral trends across 3M+ social media posts and helps creators generate content in their...](/agentkit/connectors/edenmcp/) [Vendor MCP84 tools](/agentkit/connectors/edenmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fullenrich.svg)](/agentkit/connectors/fullenrichmcp/) [Fullenrich MCPOAuth 2.1/DCR](/agentkit/connectors/fullenrichmcp/) [Connect to FullEnrich MCP. Enrich contacts with verified email addresses and phone numbers using waterfall enrichment across multiple data providers.](/agentkit/connectors/fullenrichmcp/) [Vendor MCP13 tools](/agentkit/connectors/fullenrichmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google_ads.png)](/agentkit/connectors/googleads/) [Google AdsOAuth 2.0](/agentkit/connectors/googleads/) [Connect to Google Ads to manage advertising campaigns, analyze performance metrics, and optimize ad spending across Google's advertising platform](/agentkit/connectors/googleads/) [scalekit35 tools](/agentkit/connectors/googleads/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google.svg)](/agentkit/connectors/googlebusinessprofile/) [Google Business ProfileOAuth 2.0](/agentkit/connectors/googlebusinessprofile/) [Google Business Profile lets businesses manage their presence across Google Search and Maps — business information, locations, performance/insights...](/agentkit/connectors/googlebusinessprofile/) [scalekit56 tools](/agentkit/connectors/googlebusinessprofile/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/harvestapi.svg)](/agentkit/connectors/harvestapi/) [HarvestAPIAPI Key](/agentkit/connectors/harvestapi/) [Connect to HarvestAPI to scrape LinkedIn profiles, companies, and job listings, and search for people and jobs using LinkedIn data. Enables AI agents to...](/agentkit/connectors/harvestapi/) [scalekit25 tools](/agentkit/connectors/harvestapi/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/hub_spot.svg)](/agentkit/connectors/hubspotmcp/) [HubSpot MCPOAuth 2.1](/agentkit/connectors/hubspotmcp/) [Connect to HubSpot MCP. Manage CRM contacts, companies, deals, landing pages, campaigns, and analytics from your AI workflows.](/agentkit/connectors/hubspotmcp/) [Vendor MCP22 tools](/agentkit/connectors/hubspotmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kit.svg)](/agentkit/connectors/kitmcp/) [Kit MCPOAuth 2.1/DCR](/agentkit/connectors/kitmcp/) [Connect to Kit MCP. Manage email subscribers, sequences, broadcasts, tags, and forms for your email marketing workflows.](/agentkit/connectors/kitmcp/) [Vendor MCP81 tools](/agentkit/connectors/kitmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/klaviyo.svg)](/agentkit/connectors/klaviyomcp/) [Klaviyo MCPOAuth 2.1/DCR](/agentkit/connectors/klaviyomcp/) [Connect to Klaviyo MCP. Report, strategize & create with real-time Klaviyo data](/agentkit/connectors/klaviyomcp/) [Vendor MCP263 tools](/agentkit/connectors/klaviyomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadboxer.svg)](/agentkit/connectors/leadboxermcp/) [LeadBoxer MCPOAuth 2.1/DCR](/agentkit/connectors/leadboxermcp/) [Connect to LeadBoxer MCP to identify anonymous website visitors and enrich them with firmographic data. LeadBoxer is a B2B lead generation and website...](/agentkit/connectors/leadboxermcp/) [Vendor MCP5 tools](/agentkit/connectors/leadboxermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/leadfeeder.svg)](/agentkit/connectors/leadfeedermcp/) [Leadfeeder MCPOAuth 2.1/DCR](/agentkit/connectors/leadfeedermcp/) [Connect to Leadfeeder's MCP server to identify website visitors, track B2B leads, and surface company-level intent data directly from your AI workflows.](/agentkit/connectors/leadfeedermcp/) [Vendor MCP58 tools](/agentkit/connectors/leadfeedermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lemlist.svg)](/agentkit/connectors/lemlistmcp/) [Lemlist MCPOAuth 2.1/DCR](/agentkit/connectors/lemlistmcp/) [Connect to Lemlist MCP. Manage outbound sales campaigns, leads, email sequences, and LinkedIn outreach from your AI workflows.](/agentkit/connectors/lemlistmcp/) [Vendor MCP123 tools](/agentkit/connectors/lemlistmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkedin.svg)](/agentkit/connectors/linkedin/) [LinkedInOAuth 2.0](/agentkit/connectors/linkedin/) [Connect to LinkedIn to manage posts, ads, organizations, analytics, and professional profiles from your AI workflows.](/agentkit/connectors/linkedin/) [scalekit59 tools](/agentkit/connectors/linkedin/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linkly.png)](/agentkit/connectors/linklymcp/) [LinklyHQ MCPOAuth 2.1/PKCE](/agentkit/connectors/linklymcp/) [LinklyHQ is a URL shortening and link management platform offering click analytics, custom domains, UTM tracking, QR codes, and webhook integrations for...](/agentkit/connectors/linklymcp/) [Vendor MCP25 tools](/agentkit/connectors/linklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lusha.svg)](/agentkit/connectors/lushamcp/) [Lusha MCPAPI Key](/agentkit/connectors/lushamcp/) [Connect to Lusha MCP. Search and enrich B2B contacts and companies, find lookalikes, run prospecting searches, and access intent and activity signals from...](/agentkit/connectors/lushamcp/) [Vendor MCP37 tools](/agentkit/connectors/lushamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailchimp.svg)](/agentkit/connectors/mailchimp/) [MailchimpOAuth 2.0](/agentkit/connectors/mailchimp/) [Connect to Mailchimp to manage audiences, campaigns, templates, automations, and reports.](/agentkit/connectors/mailchimp/) [scalekit73 tools](/agentkit/connectors/mailchimp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailercloud.svg)](/agentkit/connectors/mailercloudmcp/) [Mailercloud MCPOAuth 2.1/DCR](/agentkit/connectors/mailercloudmcp/) [Connect to Mailer Cloud MCP. Manage email campaigns, subscriber lists, and automation workflows for your email marketing operations.](/agentkit/connectors/mailercloudmcp/) [Vendor MCP47 tools](/agentkit/connectors/mailercloudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailerlite.svg)](/agentkit/connectors/mailerlitemcp/) [Mailerlite MCPOAuth 2.1/DCR](/agentkit/connectors/mailerlitemcp/) [Connect to MailerLite MCP. Manage email campaigns, subscribers, groups, automations, and forms from your AI workflows.](/agentkit/connectors/mailerlitemcp/) [Vendor MCP77 tools](/agentkit/connectors/mailerlitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mailgun.svg)](/agentkit/connectors/mailgun/) [MailgunAPI Key](/agentkit/connectors/mailgun/) [Connect to Mailgun to send transactional and marketing email, manage domains and DNS/DKIM security, mailing lists, suppressions (bounces, complaints...](/agentkit/connectors/mailgun/) [scalekit259 tools](/agentkit/connectors/mailgun/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metricool.svg)](/agentkit/connectors/metricoolmcp/) [Metricool MCPOAuth 2.1/DCR](/agentkit/connectors/metricoolmcp/) [Metricool is a social media analytics and scheduling platform for managing, analyzing, and scheduling content across Instagram, Twitter/X, Facebook...](/agentkit/connectors/metricoolmcp/) [Vendor MCP9 tools](/agentkit/connectors/metricoolmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/minicoursegenerator.svg)](/agentkit/connectors/minicoursegeneratormcp/) [Mini Course Generator MCPOAuth 2.1/DCR](/agentkit/connectors/minicoursegeneratormcp/) [Mini Course Generator is a platform for creating and publishing short, focused online mini-courses. It enables creators to build bite-sized educational...](/agentkit/connectors/minicoursegeneratormcp/) [Vendor MCP44 tools](/agentkit/connectors/minicoursegeneratormcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mixmax.svg)](/agentkit/connectors/mixmaxmcp/) [Mixmax MCPOAuth 2.1/DCR](/agentkit/connectors/mixmaxmcp/) [Connect to Mixmax MCP. Manage email sequences, templates, contacts, and engagement analytics from your AI workflows.](/agentkit/connectors/mixmaxmcp/) [Vendor MCP3 tools](/agentkit/connectors/mixmaxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/profound.svg)](/agentkit/connectors/profoundmcp/) [Profound MCPOAuth 2.1/DCR](/agentkit/connectors/profoundmcp/) [Profound is an AI search visibility and marketing analytics platform that helps brands understand and optimize their presence across AI-powered answer...](/agentkit/connectors/profoundmcp/) [Vendor MCP15 tools](/agentkit/connectors/profoundmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resend/) [ResendBearer Token](/agentkit/connectors/resend/) [Resend is an email API platform for developers. Send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts...](/agentkit/connectors/resend/) [scalekit101 tools](/agentkit/connectors/resend/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/resend.svg)](/agentkit/connectors/resendmcp/) [Resend MCPBearer Token](/agentkit/connectors/resendmcp/) [Connect to Resend's official MCP server to send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts, and templates...](/agentkit/connectors/resendmcp/) [Vendor MCP94 tools](/agentkit/connectors/resendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sales_force.svg)](/agentkit/connectors/salesforcemarketingcloud/) [Salesforce Marketing CloudOAuth 2.0 Server-to-Server](/agentkit/connectors/salesforcemarketingcloud/) [Connect to Salesforce Marketing Cloud to manage contacts, data extensions, automations, journeys, and email/SMS/push sends across your marketing programs.](/agentkit/connectors/salesforcemarketingcloud/) [scalekit209 tools](/agentkit/connectors/salesforcemarketingcloud/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sendgrid.svg)](/agentkit/connectors/sendgrid/) [SendGridBearer Token](/agentkit/connectors/sendgrid/) [Connect to Twilio SendGrid to send transactional and marketing email at scale, manage templates, contacts, lists, segments, and single sends, verify...](/agentkit/connectors/sendgrid/) [scalekit391 tools](/agentkit/connectors/sendgrid/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/storeleads.svg)](/agentkit/connectors/storeleadsmcp/) [StoreLeads MCPBearer Token](/agentkit/connectors/storeleadsmcp/) [Connect to StoreLeads MCP to discover, search, and analyze e-commerce stores and their technology stack from your AI workflows.](/agentkit/connectors/storeleadsmcp/) [Vendor MCP16 tools](/agentkit/connectors/storeleadsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supermetrics.svg)](/agentkit/connectors/supermetricsmcp/) [Supermetrics MCPOAuth 2.1/DCR](/agentkit/connectors/supermetricsmcp/) [Connect to Supermetrics MCP to query marketing data, discover data sources, manage campaigns, and run analytics across your connected ad and analytics...](/agentkit/connectors/supermetricsmcp/) [Vendor MCP14 tools](/agentkit/connectors/supermetricsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/surveymonkey.svg)](/agentkit/connectors/surveymonkeymcp/) [SurveyMonkey MCPOAuth 2.1/DCR](/agentkit/connectors/surveymonkeymcp/) [Connect to SurveyMonkey to manage surveys, collect responses, and analyze results. Create and update surveys, manage collectors and contacts, and retrieve...](/agentkit/connectors/surveymonkeymcp/) [Vendor MCP20 tools](/agentkit/connectors/surveymonkeymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitter/) [Twitter / XBearer Token](/agentkit/connectors/twitter/) [Connect to Twitter. Read and write Tweets, read users, manage follows, bookmarks, etc.](/agentkit/connectors/twitter/) [scalekit104 tools](/agentkit/connectors/twitter/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitterbearer/) [Twitter / XBearer Token](/agentkit/connectors/twitterbearer/) [Connect to Twitter using an App-Only Bearer Token to access public, read-only, and application-level endpoints — search, compliance jobs and streams...](/agentkit/connectors/twitterbearer/) [scalekit44 tools](/agentkit/connectors/twitterbearer/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/X.svg)](/agentkit/connectors/twitteroauth/) [Twitter / XOAuth 2.0](/agentkit/connectors/twitteroauth/) [Connect to Twitter using OAuth 2.0 (Authorization Code with PKCE) to read and write Tweets on behalf of the authenticated user, manage users, follows...](/agentkit/connectors/twitteroauth/) [scalekit92 tools](/agentkit/connectors/twitteroauth/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/typeform.svg)](/agentkit/connectors/typeformmcp/) [Typeform MCPOAuth 2.1/DCR](/agentkit/connectors/typeformmcp/) [Connect to Typeform MCP to create and manage forms, read responses, and manage workspaces, contacts, and webhooks directly from your AI workflows.](/agentkit/connectors/typeformmcp/) [Vendor MCP63 tools](/agentkit/connectors/typeformmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vibeprospecting.svg)](/agentkit/connectors/vibeprospectingmcp/) [Vibe Prospecting MCPOAuth 2.1/DCR](/agentkit/connectors/vibeprospectingmcp/) [Connect to Vibe Prospecting by Explorium to build B2B lead lists, research companies and prospects, enrich contacts, and personalize outreach from your AI...](/agentkit/connectors/vibeprospectingmcp/) [Vendor MCP14 tools](/agentkit/connectors/vibeprospectingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/windsor.svg)](/agentkit/connectors/windsoraimcp/) [Windsor.ai MCPOAuth 2.1/DCR](/agentkit/connectors/windsoraimcp/) [Connect to Windsor.ai MCP to query unified marketing and business data pulled from 350+ connected sources, discover available fields and connectors...](/agentkit/connectors/windsoraimcp/) [Vendor MCP18 tools](/agentkit/connectors/windsoraimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wordpress.svg)](/agentkit/connectors/wordpressmcp/) [WordPress MCPOAuth 2.1/DCR](/agentkit/connectors/wordpressmcp/) [Connect to WordPress.com's official MCP server to manage posts, pages, comments, media, and site settings directly from your AI workflows.](/agentkit/connectors/wordpressmcp/) [Vendor MCP19 tools](/agentkit/connectors/wordpressmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/youtube.svg)](/agentkit/connectors/youtube/) [YouTubeOAuth 2.0](/agentkit/connectors/youtube/) [Connect to YouTube to access channel details, analytics, and upload or manage videos via OAuth 2.0](/agentkit/connectors/youtube/) [scalekit45 tools](/agentkit/connectors/youtube/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zoominfo.svg)](/agentkit/connectors/zoominfo/) [ZoomInfoOAuth 2.0](/agentkit/connectors/zoominfo/) [Connect to ZoomInfo to search and enrich B2B contact and company data, access intent signals, discover technographic insights, and manage GTM Studio...](/agentkit/connectors/zoominfo/) [scalekit97 tools](/agentkit/connectors/zoominfo/) ## Media [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/claap.svg)](/agentkit/connectors/claapmcp/) [Claap MCPOAuth 2.1/DCR](/agentkit/connectors/claapmcp/) [Video collaboration platform for recording, sharing, and discussing async video clips — used for meeting recordings, product demos, feedback, and team...](/agentkit/connectors/claapmcp/) [Vendor MCP54 tools](/agentkit/connectors/claapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudinary.svg)](/agentkit/connectors/cloudinarymcp/) [Cloudinary MCPOAuth 2.1/DCR](/agentkit/connectors/cloudinarymcp/) [Connects AI agents to Cloudinary's asset management platform, enabling upload, search, transformation, and organization of media assets through natural...](/agentkit/connectors/cloudinarymcp/) [Vendor MCP30 tools](/agentkit/connectors/cloudinarymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/descript.svg)](/agentkit/connectors/descriptmcp/) [Descript MCPOAuth 2.1/DCR](/agentkit/connectors/descriptmcp/) [Connect to Descript MCP. Import media, export transcripts, publish projects, run AI editing agents, and manage jobs from your AI workflows.](/agentkit/connectors/descriptmcp/) [Vendor MCP14 tools](/agentkit/connectors/descriptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/diarize.svg)](/agentkit/connectors/diarize/) [DiarizeBearer Token](/agentkit/connectors/diarize/) [Connect to Diarize to transcribe and diarize audio and video content from YouTube, X, Instagram, and TikTok. Submit transcription jobs and retrieve...](/agentkit/connectors/diarize/) [scalekit3 tools](/agentkit/connectors/diarize/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eden.svg)](/agentkit/connectors/edenmcp/) [Eden MCPOAuth 2.1/DCR](/agentkit/connectors/edenmcp/) [Eden is an AI-powered content creation platform that discovers viral trends across 3M+ social media posts and helps creators generate content in their...](/agentkit/connectors/edenmcp/) [Vendor MCP84 tools](/agentkit/connectors/edenmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fever.svg)](/agentkit/connectors/fevermcp/) [Fever MCPOAuth 2.1/DCR](/agentkit/connectors/fevermcp/) [Fever is a live entertainment discovery platform. This MCP connector gives AI assistants direct access to Fever's global event catalog — search events by...](/agentkit/connectors/fevermcp/) [Vendor MCP2 tools](/agentkit/connectors/fevermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlecloudvision.svg)](/agentkit/connectors/googlecloudvision/) [Google Cloud VisionOAuth 2.0](/agentkit/connectors/googlecloudvision/) [Google Cloud Vision API lets you derive insights from images using pre-trained machine learning models — label detection, OCR/text extraction, face and...](/agentkit/connectors/googlecloudvision/) [scalekit27 tools](/agentkit/connectors/googlecloudvision/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlephotos.svg)](/agentkit/connectors/googlephotos/) [Google PhotosOAuth 2.0](/agentkit/connectors/googlephotos/) [Google Photos is Google's photo and video storage service for uploading, organizing into albums, and managing media created by your app.](/agentkit/connectors/googlephotos/) [scalekit17 tools](/agentkit/connectors/googlephotos/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/higgsfield.svg)](/agentkit/connectors/higgsfieldmcp/) [Higgsfield MCPOAuth 2.1/DCR](/agentkit/connectors/higgsfieldmcp/) [Connect to Higgsfield MCP to generate AI images and videos, train consistent characters, and manage your creation history across 30+ models including...](/agentkit/connectors/higgsfieldmcp/) [Vendor MCP82 tools](/agentkit/connectors/higgsfieldmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/kling.svg)](/agentkit/connectors/klingmcp/) [Kling AI MCPOAuth 2.1/DCR](/agentkit/connectors/klingmcp/) [Kling AI is a video and image generation platform. This MCP connector exposes Kling AI capabilities — including video generation and image generation —...](/agentkit/connectors/klingmcp/) [Vendor MCP10 tools](/agentkit/connectors/klingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metricool.svg)](/agentkit/connectors/metricoolmcp/) [Metricool MCPOAuth 2.1/DCR](/agentkit/connectors/metricoolmcp/) [Metricool is a social media analytics and scheduling platform for managing, analyzing, and scheduling content across Instagram, Twitter/X, Facebook...](/agentkit/connectors/metricoolmcp/) [Vendor MCP9 tools](/agentkit/connectors/metricoolmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mux.svg)](/agentkit/connectors/muxmcp/) [Mux MCPOAuth 2.1/DCR](/agentkit/connectors/muxmcp/) [Mux is a video infrastructure platform for developers, providing APIs for video hosting, on-demand streaming, live streaming, and playback with analytics...](/agentkit/connectors/muxmcp/) [Vendor MCP2 tools](/agentkit/connectors/muxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pixelbin.svg)](/agentkit/connectors/pixelbinmcp/) [Pixelbin MCPOAuth 2.1/DCR](/agentkit/connectors/pixelbinmcp/) [Image and video transformation, optimization, and management platform.](/agentkit/connectors/pixelbinmcp/) [Vendor MCP7 tools](/agentkit/connectors/pixelbinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plaud.svg)](/agentkit/connectors/plaudmcp/) [Plaud MCPOAuth 2.1/DCR](/agentkit/connectors/plaudmcp/) [Connect to Plaud MCP. Browse your Plaud recordings, read AI-generated notes, and pull timestamped transcripts with speaker labels into your AI workflows.](/agentkit/connectors/plaudmcp/) [Vendor MCP5 tools](/agentkit/connectors/plaudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quizvideo.svg)](/agentkit/connectors/quizvideomcp/) [Quiz.Video MCPOAuth 2.1/DCR](/agentkit/connectors/quizvideomcp/) [Quiz.Video is an AI-powered platform for creating short-form quiz and flashcard videos. Transform topics, URLs, or documents into shareable quiz and...](/agentkit/connectors/quizvideomcp/) [Vendor MCP30 tools](/agentkit/connectors/quizvideomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/reddit.svg)](/agentkit/connectors/reddit/) [RedditOAuth 2.0](/agentkit/connectors/reddit/) [Connect to Reddit to access user identity, subreddit data, posts, comments, and mod tools.](/agentkit/connectors/reddit/) [scalekit105 tools](/agentkit/connectors/reddit/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/runware.svg)](/agentkit/connectors/runwaremcp/) [Runware MCPOAuth 2.1/DCR](/agentkit/connectors/runwaremcp/) [Connect to Runware's MCP server to generate and edit images, video, audio, and 3D assets using thousands of AI models through a single API.](/agentkit/connectors/runwaremcp/) [Vendor MCP12 tools](/agentkit/connectors/runwaremcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/splice.svg)](/agentkit/connectors/splicemcp/) [Splice MCPOAuth 2.1/DCR](/agentkit/connectors/splicemcp/) [Connect to Splice MCP. Search the Splice sample catalog, create and update multi-track stacks, download audio assets, and generate arrangements from text...](/agentkit/connectors/splicemcp/) [Vendor MCP6 tools](/agentkit/connectors/splicemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vimeo.svg)](/agentkit/connectors/vimeo/) [VimeoOAuth 2.0](/agentkit/connectors/vimeo/) [Connect to Vimeo API v3.4. Upload and manage videos, organize content into showcases and folders, manage channels, handle comments, likes, and webhooks.](/agentkit/connectors/vimeo/) [scalekit59 tools](/agentkit/connectors/vimeo/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wordpress.svg)](/agentkit/connectors/wordpressmcp/) [WordPress MCPOAuth 2.1/DCR](/agentkit/connectors/wordpressmcp/) [Connect to WordPress.com's official MCP server to manage posts, pages, comments, media, and site settings directly from your AI workflows.](/agentkit/connectors/wordpressmcp/) [Vendor MCP19 tools](/agentkit/connectors/wordpressmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/youtube.svg)](/agentkit/connectors/youtube/) [YouTubeOAuth 2.0](/agentkit/connectors/youtube/) [Connect to YouTube to access channel details, analytics, and upload or manage videos via OAuth 2.0](/agentkit/connectors/youtube/) [scalekit45 tools](/agentkit/connectors/youtube/) ## Monitoring [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agencyanalytics.svg)](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics MCPOAuth 2.1/DCR](/agentkit/connectors/agencyanalyticsmcp/) [Agency Analytics is a marketing reporting platform that enables digital agencies to monitor SEO, PPC, social media, and other channel performance in...](/agentkit/connectors/agencyanalyticsmcp/) [Vendor MCP35 tools](/agentkit/connectors/agencyanalyticsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/appsignal.svg)](/agentkit/connectors/appsignalmcp/) [AppSignal MCPOAuth 2.1/DCR](/agentkit/connectors/appsignalmcp/) [AppSignal is an application monitoring and performance management platform providing error tracking, performance monitoring, and alerting for Ruby...](/agentkit/connectors/appsignalmcp/) [Vendor MCP25 tools](/agentkit/connectors/appsignalmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/axiom.svg)](/agentkit/connectors/axiommcp/) [Axiom MCPOAuth 2.1/DCR](/agentkit/connectors/axiommcp/) [Axiom is a cloud-native data analytics and observability platform for ingesting, storing, and querying logs, events, traces, and metrics at scale. The MCP...](/agentkit/connectors/axiommcp/) [Vendor MCP26 tools](/agentkit/connectors/axiommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/betterstack.svg)](/agentkit/connectors/betterstackmcp/) [Betterstack MCPOAuth 2.1/DCR](/agentkit/connectors/betterstackmcp/) [Monitor uptime, manage logs, and respond to incidents with Better Stack's observability platform.](/agentkit/connectors/betterstackmcp/) [Vendor MCP107 tools](/agentkit/connectors/betterstackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bugsnag.svg)](/agentkit/connectors/bugsnagmcp/) [Bugsnag MCPOAuth 2.1/DCR](/agentkit/connectors/bugsnagmcp/) [Connect to Bugsnag MCP. Monitor errors, releases, traces, and span groups across your projects from your AI workflows.](/agentkit/connectors/bugsnagmcp/) [Vendor MCP19 tools](/agentkit/connectors/bugsnagmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudflare.svg)](/agentkit/connectors/cloudflare/) [CloudflareOAuth 2.0](/agentkit/connectors/cloudflare/) [Cloudflare is a cloud platform providing DNS management, CDN, security, and networking services. This connector enables automated management of zones, DNS...](/agentkit/connectors/cloudflare/) [scalekit31 tools](/agentkit/connectors/cloudflare/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/databox.svg)](/agentkit/connectors/databoxmcp/) [Databox MCPOAuth 2.1/DCR](/agentkit/connectors/databoxmcp/) [Connect to Databox MCP. Query metrics, manage dashboards, and push custom data to your Databox analytics and reporting platform.](/agentkit/connectors/databoxmcp/) [Vendor MCP19 tools](/agentkit/connectors/databoxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/datadog.svg)](/agentkit/connectors/datadog/) [DatadogAPI Key](/agentkit/connectors/datadog/) [Connect to Datadog to monitor metrics, logs, traces, dashboards, monitors, incidents, SLOs, synthetics, and security signals across your infrastructure.](/agentkit/connectors/datadog/) [scalekit105 tools](/agentkit/connectors/datadog/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/globalping.svg)](/agentkit/connectors/globalpingmcp/) [Globalping MCPOAuth 2.1/DCR](/agentkit/connectors/globalpingmcp/) [Globalping is a global network measurement platform for running ping, traceroute, DNS lookup, HTTP, and MTR tests from hundreds of probe locations...](/agentkit/connectors/globalpingmcp/) [Vendor MCP12 tools](/agentkit/connectors/globalpingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gtmetrix.svg)](/agentkit/connectors/gtmetrixmcp/) [GTmetrix MCPOAuth 2.1/DCR](/agentkit/connectors/gtmetrixmcp/) [Connect to GTmetrix MCP to analyze web page performance, run speed tests, monitor Core Web Vitals, and get actionable optimization recommendations...](/agentkit/connectors/gtmetrixmcp/) [Vendor MCP10 tools](/agentkit/connectors/gtmetrixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jam.svg)](/agentkit/connectors/jammcp/) [Jam MCPOAuth 2.1/DCR](/agentkit/connectors/jammcp/) [Connect to Jam MCP. Access bug reports, console logs, network requests, user events, and video transcripts from your AI workflows.](/agentkit/connectors/jammcp/) [Vendor MCP15 tools](/agentkit/connectors/jammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/launchdarkly.svg)](/agentkit/connectors/launchdarklymcp/) [LaunchDarkly MCPOAuth 2.1/DCR](/agentkit/connectors/launchdarklymcp/) [Connect to LaunchDarkly's hosted MCP server to manage feature flags, experiments, and release controls directly from your AI workflows.](/agentkit/connectors/launchdarklymcp/) [Vendor MCP136 tools](/agentkit/connectors/launchdarklymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/logrocket.svg)](/agentkit/connectors/logrocketmcp/) [LogRocket MCPOAuth 2.1/DCR](/agentkit/connectors/logrocketmcp/) [Connect to LogRocket to access session data, query analytics, investigate user-reported issues, and detect regressions directly from your AI workflows.](/agentkit/connectors/logrocketmcp/) [Vendor MCP8 tools](/agentkit/connectors/logrocketmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pagerduty.svg)](/agentkit/connectors/pagerduty/) [PagerDutyOAuth 2.0](/agentkit/connectors/pagerduty/) [Connect to PagerDuty to manage incidents, services, users, teams, escalation policies, schedules, and on-call rotations.](/agentkit/connectors/pagerduty/) [scalekit71 tools](/agentkit/connectors/pagerduty/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pendo.svg)](/agentkit/connectors/pendomcp/) [Pendo MCPOAuth 2.1/DCR](/agentkit/connectors/pendomcp/) [Connect to Pendo MCP to access product analytics, user guidance, and engagement data directly from your AI workflows.](/agentkit/connectors/pendomcp/) [Vendor MCP45 tools](/agentkit/connectors/pendomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quicknode.svg)](/agentkit/connectors/quicknodemcp/) [Quicknode MCPOAuth 2.1/DCR](/agentkit/connectors/quicknodemcp/) [Connect to QuickNode MCP. Create and manage blockchain RPC endpoints, configure security rules, set rate limits, and monitor usage and logs from your AI...](/agentkit/connectors/quicknodemcp/) [Vendor MCP19 tools](/agentkit/connectors/quicknodemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sentry.svg)](/agentkit/connectors/sentrymcp/) [Sentry MCPOAuth 2.1/DCR](/agentkit/connectors/sentrymcp/) [Connect to Sentry MCP server to monitor errors, investigate issues, manage projects, and analyze performance directly from your AI workflows.](/agentkit/connectors/sentrymcp/) [Vendor MCP9 tools](/agentkit/connectors/sentrymcp/) [![](https://dac-static.atlassian.com/_static/Statuspage-blue.svg)](/agentkit/connectors/statuspage/) [StatuspageAPI Key](/agentkit/connectors/statuspage/) [Connect to Statuspage. Manage status pages, incidents, components, component groups, subscribers, metrics, and page access permissions.](/agentkit/connectors/statuspage/) [scalekit99 tools](/agentkit/connectors/statuspage/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/testdino.svg)](/agentkit/connectors/testidinomcp/) [Testdino MCPOAuth 2.1/DCR](/agentkit/connectors/testidinomcp/) [TestDino is a Playwright test reporting and analytics platform that centralizes test data, detects flaky tests, and provides AI-powered debugging via MCP...](/agentkit/connectors/testidinomcp/) [Vendor MCP38 tools](/agentkit/connectors/testidinomcp/) ## Productivity [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/agentmail.svg)](/agentkit/connectors/agentmailmcp/) [Agentmail MCPOAuth 2.1/DCR](/agentkit/connectors/agentmailmcp/) [Connect to Agentmail MCP. Manage inboxes, send and receive email, handle drafts, threads, and attachments from your AI workflows.](/agentkit/connectors/agentmailmcp/) [Vendor MCP26 tools](/agentkit/connectors/agentmailmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtablemcp/) [Airtable MCPOAuth 2.1/DCR](/agentkit/connectors/airtablemcp/) [Connect to Airtable MCP. Manage bases, tables, records, views, fields, and automations from your AI workflows.](/agentkit/connectors/airtablemcp/) [Vendor MCP43 tools](/agentkit/connectors/airtablemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/anakin.svg)](/agentkit/connectors/anakinmcp/) [Anakin MCPOAuth 2.1/DCR](/agentkit/connectors/anakinmcp/) [Anakin is an AI platform and marketplace that lets you build, deploy, and access a wide range of AI tools and automated workflows. This MCP connector...](/agentkit/connectors/anakinmcp/) [Vendor MCP21 tools](/agentkit/connectors/anakinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asana/) [AsanaOAuth 2.0](/agentkit/connectors/asana/) [Connect to Asana. Manage tasks, projects, teams, and workflow automation](/agentkit/connectors/asana/) [scalekit210 tools](/agentkit/connectors/asana/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asanamcp/) [Asana MCPOAuth 2.1](/agentkit/connectors/asanamcp/) [Connect to Asana MCP server to manage tasks, projects, and teams directly from your AI workflows.](/agentkit/connectors/asanamcp/) [Vendor MCP38 tools](/agentkit/connectors/asanamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/atlassian.svg)](/agentkit/connectors/atlassianmcp/) [Atlassian Rovo MCPOAuth 2.1/DCR](/agentkit/connectors/atlassianmcp/) [Connect to Atlassian Rovo MCP server to manage Jira issues, Confluence pages, and Compass components directly from your AI workflows.](/agentkit/connectors/atlassianmcp/) [Vendor MCP39 tools](/agentkit/connectors/atlassianmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/attio.svg)](/agentkit/connectors/attiomcp/) [Attio MCPOAuth 2.1/DCR](/agentkit/connectors/attiomcp/) [Connect to Attio MCP. Access and manage CRM records, lists, notes, tasks, emails, and workspace data across people, companies, and deals.](/agentkit/connectors/attiomcp/) [Vendor MCP38 tools](/agentkit/connectors/attiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bonsai.svg)](/agentkit/connectors/bonsaimcp/) [Bonsai MCPOAuth 2.1/DCR](/agentkit/connectors/bonsaimcp/) [Connect to Bonsai, the all-in-one business management platform for freelancers and agencies. Manage projects, tasks, CRM contacts, deals, invoices, and...](/agentkit/connectors/bonsaimcp/) [Vendor MCP34 tools](/agentkit/connectors/bonsaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg)](/agentkit/connectors/box/) [BoxOAuth 2.0](/agentkit/connectors/box/) [Box is a cloud content management platform. Manage files, folders, users, groups, collaborations, tasks, comments, webhooks, search, and more using the...](/agentkit/connectors/box/) [scalekit102 tools](/agentkit/connectors/box/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/box.svg)](/agentkit/connectors/boxmcp/) [Box MCPOAuth 2.1](/agentkit/connectors/boxmcp/) [Connect to Box via MCP to manage files, folders, collaborations, users, groups, tasks, comments, and search content directly from your AI workflows.](/agentkit/connectors/boxmcp/) [Vendor MCP44 tools](/agentkit/connectors/boxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cal.svg)](/agentkit/connectors/calmcp/) [Cal MCPOAuth 2.1/DCR](/agentkit/connectors/calmcp/) [Connect to Cal MCP. Manage bookings, event types, schedules, and availability from your AI workflows.](/agentkit/connectors/calmcp/) [Vendor MCP35 tools](/agentkit/connectors/calmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/calendly.svg)](/agentkit/connectors/calendly/) [CalendlyOAuth 2.0](/agentkit/connectors/calendly/) [Connect to Calendly. Access user profile, events, and scheduling workflows.](/agentkit/connectors/calendly/) [scalekit64 tools](/agentkit/connectors/calendly/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/calendly.svg)](/agentkit/connectors/calendlymcp/) [Calendly MCPOAuth 2.1/DCR](/agentkit/connectors/calendlymcp/) [Connect to the Calendly MCP server to manage scheduled events, invitees, event types, and availability directly from your AI workflows.](/agentkit/connectors/calendlymcp/) [Vendor MCP36 tools](/agentkit/connectors/calendlymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/carta.svg)](/agentkit/connectors/cartamcp/) [Carta MCPOAuth 2.1/DCR](/agentkit/connectors/cartamcp/) [Connect to Carta. Manage equity cap tables, fund administration, company accounts, and ownership data for venture-backed companies.](/agentkit/connectors/cartamcp/) [Vendor MCP18 tools](/agentkit/connectors/cartamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chilipiper.svg)](/agentkit/connectors/chilipipermcp/) [ChiliPiper MCPBearer Token](/agentkit/connectors/chilipipermcp/) [Connect to ChiliPiper MCP. Schedule meetings, manage routing rules, track distributions, and automate handoffs from your AI agents.](/agentkit/connectors/chilipipermcp/) [Vendor MCP156 tools](/agentkit/connectors/chilipipermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/circleback.svg)](/agentkit/connectors/circlebackmcp/) [Circleback MCPOAuth 2.1/DCR](/agentkit/connectors/circlebackmcp/) [Circleback is an AI meeting notes and conversation intelligence platform. The Circleback MCP server provides a standardized interface that allows any...](/agentkit/connectors/circlebackmcp/) [Vendor MCP11 tools](/agentkit/connectors/circlebackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/claap.svg)](/agentkit/connectors/claapmcp/) [Claap MCPOAuth 2.1/DCR](/agentkit/connectors/claapmcp/) [Video collaboration platform for recording, sharing, and discussing async video clips — used for meeting recordings, product demos, feedback, and team...](/agentkit/connectors/claapmcp/) [Vendor MCP54 tools](/agentkit/connectors/claapmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clarify.svg)](/agentkit/connectors/clarifymcp/) [Clarify MCPOAuth 2.1/DCR](/agentkit/connectors/clarifymcp/) [Connect to Clarify MCP to manage CRM records, leads, campaigns, lists, and analytics directly from your AI workflows.](/agentkit/connectors/clarifymcp/) [Vendor MCP38 tools](/agentkit/connectors/clarifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickup/) [ClickUpOAuth 2.0](/agentkit/connectors/clickup/) [Connect to ClickUp. Manage tasks, projects, workspaces, and team collaboration](/agentkit/connectors/clickup/) [scalekit99 tools](/agentkit/connectors/clickup/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickupmcp/) [ClickUp MCPOAuth 2.1/DCR](/agentkit/connectors/clickupmcp/) [Connect to ClickUp MCP to manage tasks, projects, spaces, and workspaces directly from your AI workflows.](/agentkit/connectors/clickupmcp/) [Vendor MCP57 tools](/agentkit/connectors/clickupmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/cloudpress.svg)](/agentkit/connectors/cloudpressmcp/) [Cloudpress MCPOAuth 2.1/DCR](/agentkit/connectors/cloudpressmcp/) [Cloudpress is a managed WordPress hosting platform built for the AI era. Its MCP server lets AI agents manage sites, domains, DNS, security rules...](/agentkit/connectors/cloudpressmcp/) [Vendor MCP66 tools](/agentkit/connectors/cloudpressmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/contentful.svg)](/agentkit/connectors/contentfulmcp/) [Contentful MCPOAuth 2.1/DCR](/agentkit/connectors/contentfulmcp/) [Connect to Contentful MCP. Manage spaces, entries, assets, content types, and taxonomies in your Contentful CMS from AI workflows.](/agentkit/connectors/contentfulmcp/) [Vendor MCP70 tools](/agentkit/connectors/contentfulmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/context7.svg)](/agentkit/connectors/context7mcp/) [Context7 MCPAPI Key](/agentkit/connectors/context7mcp/) [Connect to Context7 MCP to fetch up-to-date, version-specific library documentation and code examples directly from the source.](/agentkit/connectors/context7mcp/) [Vendor MCP2 tools](/agentkit/connectors/context7mcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/conversiontools.svg)](/agentkit/connectors/conversiontoolsmcp/) [Conversion Tools MCPOAuth 2.1/DCR](/agentkit/connectors/conversiontoolsmcp/) [Connect to Conversion Tools MCP. Convert files between 140+ formats including documents, images, audio, video, and data files from your AI workflows.](/agentkit/connectors/conversiontoolsmcp/) [Vendor MCP23 tools](/agentkit/connectors/conversiontoolsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dartai.svg)](/agentkit/connectors/dartaimcp/) [Dart AI MCPOAuth 2.1/DCR](/agentkit/connectors/dartaimcp/) [AI-native project management tool for task and document management with deep AI integration.](/agentkit/connectors/dartaimcp/) [Vendor MCP29 tools](/agentkit/connectors/dartaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deel.svg)](/agentkit/connectors/deelmcp/) [Deel MCPOAuth 2.1/DCR](/agentkit/connectors/deelmcp/) [Global HR and payroll platform for hiring, paying, and managing international employees and contractors with built-in compliance.](/agentkit/connectors/deelmcp/) [Vendor MCP355 tools](/agentkit/connectors/deelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deepl.svg)](/agentkit/connectors/deeplmcp/) [DeepL MCPOAuth 2.1/DCR](/agentkit/connectors/deeplmcp/) [Connect to DeepL's MCP server to translate and rephrase text, correct grammar, translate documents, and manage glossaries and writing styles.](/agentkit/connectors/deeplmcp/) [Vendor MCP8 tools](/agentkit/connectors/deeplmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/descript.svg)](/agentkit/connectors/descriptmcp/) [Descript MCPOAuth 2.1/DCR](/agentkit/connectors/descriptmcp/) [Connect to Descript MCP. Import media, export transcripts, publish projects, run AI editing agents, and manage jobs from your AI workflows.](/agentkit/connectors/descriptmcp/) [Vendor MCP14 tools](/agentkit/connectors/descriptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/diarize.svg)](/agentkit/connectors/diarize/) [DiarizeBearer Token](/agentkit/connectors/diarize/) [Connect to Diarize to transcribe and diarize audio and video content from YouTube, X, Instagram, and TikTok. Submit transcription jobs and retrieve...](/agentkit/connectors/diarize/) [scalekit3 tools](/agentkit/connectors/diarize/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/drop_box.svg)](/agentkit/connectors/dropboxmcp/) [Dropbox MCPOAuth 2.1](/agentkit/connectors/dropboxmcp/) [Connect to Dropbox. Manage files and folders, create shared links, search content, and handle file requests from your AI workflows.](/agentkit/connectors/dropboxmcp/) [Vendor MCP25 tools](/agentkit/connectors/dropboxmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/eracontext.svg)](/agentkit/connectors/eracontextmcp/) [Era Context MCPOAuth 2.1/DCR](/agentkit/connectors/eracontextmcp/) [Connect to Era Context MCP. Access personal finance data including transactions, accounts, spending insights, and AI-powered financial knowledge from Era.](/agentkit/connectors/eracontextmcp/) [Vendor MCP51 tools](/agentkit/connectors/eracontextmcp/) [![](https://docs.excalidraw.com/img/logo.svg)](/agentkit/connectors/excalidrawmcp/) [Excalidraw MCPBearer Token](/agentkit/connectors/excalidrawmcp/) [Excalidraw+ is a collaborative whiteboard and diagramming platform. The Excalidraw MCP server lets AI agents manage scenes, collections, workspaces...](/agentkit/connectors/excalidrawmcp/) [Vendor MCP29 tools](/agentkit/connectors/excalidrawmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathommcp/) [Fathom MCPOAuth 2.1/DCR](/agentkit/connectors/fathommcp/) [Connect to Fathom MCP to access AI meeting notes, summaries, transcripts, and recordings from your AI workflows.](/agentkit/connectors/fathommcp/) [Vendor MCP9 tools](/agentkit/connectors/fathommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fellowai.svg)](/agentkit/connectors/fellowaimcp/) [FellowAI MCPOAuth 2.1/DCR](/agentkit/connectors/fellowaimcp/) [Connect to Fellow.ai MCP to manage meeting notes, action items, agendas, and team collaboration workflows directly from your AI agent.](/agentkit/connectors/fellowaimcp/) [Vendor MCP7 tools](/agentkit/connectors/fellowaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/felt.svg)](/agentkit/connectors/feltmcp/) [FeltOAuth 2.1/DCR](/agentkit/connectors/feltmcp/) [Connect to Felt, a cloud-native GIS and mapping platform, to manage maps, layers, and geospatial data, query connected spatial databases, and collaborate...](/agentkit/connectors/feltmcp/) [Vendor MCP44 tools](/agentkit/connectors/feltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fibery.svg)](/agentkit/connectors/fiberymcp/) [Fibery MCPOAuth 2.1/DCR](/agentkit/connectors/fiberymcp/) [Connect to Fibery MCP. Query, create, and update entities across your Fibery workspace using the Fibery API and AI assistant.](/agentkit/connectors/fiberymcp/) [Vendor MCP80 tools](/agentkit/connectors/fiberymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fireflies.svg)](/agentkit/connectors/firefliesmcp/) [Fireflies MCPOAuth 2.1/DCR](/agentkit/connectors/firefliesmcp/) [Connect to Fireflies MCP. Search meeting transcripts, fetch recordings, manage channels, create soundbites, and retrieve analytics from your AI workflows.](/agentkit/connectors/firefliesmcp/) [Vendor MCP20 tools](/agentkit/connectors/firefliesmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googleclassroom.svg)](/agentkit/connectors/googleclassroom/) [Google ClassroomOAuth 2.0](/agentkit/connectors/googleclassroom/) [Google Classroom is Google's free web-based platform for schools that streamlines creating, distributing, and grading assignments, and simplifies...](/agentkit/connectors/googleclassroom/) [scalekit76 tools](/agentkit/connectors/googleclassroom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlecontacts.svg)](/agentkit/connectors/googlecontacts/) [Google ContactsOAuth 2.0](/agentkit/connectors/googlecontacts/) [Google Contacts (People API) lets you manage your contacts, contact groups, and directory information. Create, read, update, and delete contacts and...](/agentkit/connectors/googlecontacts/) [scalekit24 tools](/agentkit/connectors/googlecontacts/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlelooker.svg)](/agentkit/connectors/googlelooker/) [Google LookerOAuth 2.0](/agentkit/connectors/googlelooker/) [Connect to Google Looker or self-hosted Looker Core. Browse dashboards, run Looks, query LookML models, and access BI data programmatically.](/agentkit/connectors/googlelooker/) [scalekit31 tools](/agentkit/connectors/googlelooker/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googletasks.svg)](/agentkit/connectors/googletasks/) [Google TasksOAuth 2.0](/agentkit/connectors/googletasks/) [Google Tasks is Google's task management service for creating and organizing to-do items and task lists, synced across Gmail, Calendar, and mobile devices.](/agentkit/connectors/googletasks/) [scalekit12 tools](/agentkit/connectors/googletasks/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/google.svg)](/agentkit/connectors/googledwd/) [Google Workspace (DWD)Service Account (DWD)](/agentkit/connectors/googledwd/) [Connect to Google Workspace APIs (Gmail, Drive, Docs, Sheets, Slides, Forms) using a GCP service account with Domain-Wide Delegation for server-to-server...](/agentkit/connectors/googledwd/) [scalekit100 tools](/agentkit/connectors/googledwd/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gusto.svg)](/agentkit/connectors/gustomcp/) [Gusto MCPOAuth 2.1/DCR](/agentkit/connectors/gustomcp/) [Connect to Gusto MCP. Manage employees, contractors, payroll, departments, and company data from your AI workflows.](/agentkit/connectors/gustomcp/) [Vendor MCP50 tools](/agentkit/connectors/gustomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/harvestapp.svg)](/agentkit/connectors/harvestmcp/) [Harvest MCPOAuth 2.1/DCR](/agentkit/connectors/harvestmcp/) [Harvest is a time tracking and invoicing tool that helps teams track time, manage projects, and create invoices.](/agentkit/connectors/harvestmcp/) [Vendor MCP36 tools](/agentkit/connectors/harvestmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/igpt.svg)](/agentkit/connectors/igptmcp/) [IGPT MCPOAuth 2.1/DCR](/agentkit/connectors/igptmcp/) [IGPT is an AI assistant platform that exposes its capabilities via an MCP server, enabling agents to interact with AI-powered tools and workflows.](/agentkit/connectors/igptmcp/) [Vendor MCP2 tools](/agentkit/connectors/igptmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jotform.svg)](/agentkit/connectors/jotformmcp/) [Jotform MCPOAuth 2.1/DCR](/agentkit/connectors/jotformmcp/) [Connect to Jotform MCP. Create and edit forms, retrieve submissions, assign forms, and search assets from your AI workflows.](/agentkit/connectors/jotformmcp/) [Vendor MCP7 tools](/agentkit/connectors/jotformmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/loops.svg)](/agentkit/connectors/loopsmcp/) [Loops MCPOAuth 2.1/DCR](/agentkit/connectors/loopsmcp/) [Connect to Loops MCP. Create and manage loops and tasks, set priorities, track work queue stats, and ship completed loops from your AI workflows.](/agentkit/connectors/loopsmcp/) [Vendor MCP20 tools](/agentkit/connectors/loopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lucid.svg)](/agentkit/connectors/lucidmcp/) [Lucid MCPOAuth 2.1/DCR](/agentkit/connectors/lucidmcp/) [Connect to Lucid. Create and edit Lucidchart diagrams, Lucidspark boards, and Lucidscale visualizations from your AI workflows.](/agentkit/connectors/lucidmcp/) [Vendor MCP35 tools](/agentkit/connectors/lucidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/make.svg)](/agentkit/connectors/makemcp/) [Make MCPOAuth 2.1/DCR](/agentkit/connectors/makemcp/) [Connect to Make (formerly Integromat). Build, run, and manage automation scenarios, data stores, webhooks, and connections across thousands of apps from...](/agentkit/connectors/makemcp/) [Vendor MCP163 tools](/agentkit/connectors/makemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mem.svg)](/agentkit/connectors/memmcp/) [Mem MCPOAuth 2.1/DCR](/agentkit/connectors/memmcp/) [A hosted MCP server that gives AI tools secure access to your Mem notes and collections — enabling AI agents to read, create, search, and organize notes...](/agentkit/connectors/memmcp/) [Vendor MCP23 tools](/agentkit/connectors/memmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mercury.svg)](/agentkit/connectors/mercurymcp/) [Mercury MCPOAuth 2.1/DCR](/agentkit/connectors/mercurymcp/) [Connect to Mercury. Access accounts, transactions, recipients, invoices, treasury, webhooks, and approval requests for startup banking workflows.](/agentkit/connectors/mercurymcp/) [Vendor MCP35 tools](/agentkit/connectors/mercurymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/metaview.svg)](/agentkit/connectors/metaviewmcp/) [Metaview MCPOAuth 2.1/DCR](/agentkit/connectors/metaviewmcp/) [Metaview is an agentic recruiting platform that automates end-to-end hiring workflows — from candidate sourcing and outreach to interview note-taking and...](/agentkit/connectors/metaviewmcp/) [Vendor MCP46 tools](/agentkit/connectors/metaviewmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/microsoft365.svg)](/agentkit/connectors/microsoft365/) [Microsoft 365OAuth 2.0](/agentkit/connectors/microsoft365/) [Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API.](/agentkit/connectors/microsoft365/) [scalekit313 tools](/agentkit/connectors/microsoft365/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mintlify.svg)](/agentkit/connectors/mintlifymcp/) [Mintlify MCPOAuth 2.1/DCR](/agentkit/connectors/mintlifymcp/) [Connect to Mintlify MCP. Read and edit documentation pages, manage navigation nodes, search content, and publish changes via pull requests from your AI...](/agentkit/connectors/mintlifymcp/) [Vendor MCP19 tools](/agentkit/connectors/mintlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miro/) [MiroOAuth 2.0](/agentkit/connectors/miro/) [Miro is a visual collaboration platform for teams. Manage boards, sticky notes, shapes, cards, frames, connectors, images, and tags using the Miro REST...](/agentkit/connectors/miro/) [scalekit115 tools](/agentkit/connectors/miro/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/Miro.svg)](/agentkit/connectors/miromcp/) [Miro MCPOAuth 2.1/DCR](/agentkit/connectors/miromcp/) [Connect to Miro MCP to create and manage boards, frames, sticky notes, shapes, diagrams, and comments directly from your AI workflows.](/agentkit/connectors/miromcp/) [Vendor MCP65 tools](/agentkit/connectors/miromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/mondaymcp/) [Monday MCPOAuth 2.1/DCR](/agentkit/connectors/mondaymcp/) [Connect to the monday.com MCP server to manage boards, items, columns, docs, and workflows directly from your AI agents.](/agentkit/connectors/mondaymcp/) [Vendor MCP94 tools](/agentkit/connectors/mondaymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/monday/) [Monday.comOAuth 2.0](/agentkit/connectors/monday/) [Connect to Monday.com. Manage boards, tasks, workflows, teams, and project collaboration](/agentkit/connectors/monday/) [scalekit73 tools](/agentkit/connectors/monday/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motion.svg)](/agentkit/connectors/motionmcp/) [Motion MCPOAuth 2.1/DCR](/agentkit/connectors/motionmcp/) [Connect to Motion MCP. Manage tasks, projects, workspaces, and schedules in the Motion AI-powered project management platform.](/agentkit/connectors/motionmcp/) [Vendor MCP14 tools](/agentkit/connectors/motionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/netlify.svg)](/agentkit/connectors/netlifymcp/) [Netlify MCPOAuth 2.1/DCR](/agentkit/connectors/netlifymcp/) [Build, deploy, and manage Netlify projects — sites, functions, environment variables, forms, blobs, and edge functions — from AI agents via the Netlify...](/agentkit/connectors/netlifymcp/) [Vendor MCP9 tools](/agentkit/connectors/netlifymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nocodb.svg)](/agentkit/connectors/nocodbmcp/) [NocoDB MCPOAuth 2.1/DCR](/agentkit/connectors/nocodbmcp/) [Connect to NocoDB MCP. Create and manage databases, tables, records, views, and fields from your AI workflows.](/agentkit/connectors/nocodbmcp/) [Vendor MCP11 tools](/agentkit/connectors/nocodbmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notionmcp/) [Notion MCPOAuth 2.1/DCR](/agentkit/connectors/notionmcp/) [Connect to Notion MCP. Create and update pages, databases, comments, and views from your AI workflows.](/agentkit/connectors/notionmcp/) [Vendor MCP28 tools](/agentkit/connectors/notionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/otterai.svg)](/agentkit/connectors/otteraimcp/) [OtterAI MCPOAuth 2.1/DCR](/agentkit/connectors/otteraimcp/) [Connect to OtterAI MCP. Search meeting recordings, fetch full transcripts, and retrieve user account info from your AI workflows.](/agentkit/connectors/otteraimcp/) [Vendor MCP3 tools](/agentkit/connectors/otteraimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pandadoc.svg)](/agentkit/connectors/pandadocmcp/) [Pandadoc MCPOAuth 2.1/DCR](/agentkit/connectors/pandadocmcp/) [Connect to PandaDoc MCP. Create, send, and manage documents, templates, and e-signatures directly from your AI workflows.](/agentkit/connectors/pandadocmcp/) [Vendor MCP22 tools](/agentkit/connectors/pandadocmcp/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/parallel-ai.svg)](/agentkit/connectors/parallelaitaskmcp/) [Parallel AI Task MCPBearer Token](/agentkit/connectors/parallelaitaskmcp/) [Connect to Parallel AI Task MCP to run deep research tasks and task groups directly from your AI workflows.](/agentkit/connectors/parallelaitaskmcp/) [Vendor MCP4 tools](/agentkit/connectors/parallelaitaskmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plain.svg)](/agentkit/connectors/plainmcp/) [Plain MCPOAuth 2.1/DCR](/agentkit/connectors/plainmcp/) [Connect to Plain MCP. Manage customer support threads, labels, tenants, Help Center articles, and thread field schemas directly from your AI workflows.](/agentkit/connectors/plainmcp/) [Vendor MCP63 tools](/agentkit/connectors/plainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plane.svg)](/agentkit/connectors/planemcp/) [Plane MCPOAuth 2.1/DCR](/agentkit/connectors/planemcp/) [Connect to Plane MCP. Manage projects, work items, cycles, modules, epics, and initiatives in your Plane workspace from AI workflows.](/agentkit/connectors/planemcp/) [Vendor MCP109 tools](/agentkit/connectors/planemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/planningcenter.svg)](/agentkit/connectors/planningcentermcp/) [Planning Center MCPOAuth 2.1/DCR](/agentkit/connectors/planningcentermcp/) [Planning Center is a church management platform with modules for people (contact database), giving, check-ins, services planning, groups, registrations...](/agentkit/connectors/planningcentermcp/) [Vendor MCP64 tools](/agentkit/connectors/planningcentermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plaud.svg)](/agentkit/connectors/plaudmcp/) [Plaud MCPOAuth 2.1/DCR](/agentkit/connectors/plaudmcp/) [Connect to Plaud MCP. Browse your Plaud recordings, read AI-generated notes, and pull timestamped transcripts with speaker labels into your AI workflows.](/agentkit/connectors/plaudmcp/) [Vendor MCP5 tools](/agentkit/connectors/plaudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/privacy.svg)](/agentkit/connectors/privacymcp/) [Privacy MCPOAuth 2.1/DCR](/agentkit/connectors/privacymcp/) [Connect to Privacy MCP. Create and manage virtual cards, set spend limits, pause or close cards, and review transactions from your AI workflows.](/agentkit/connectors/privacymcp/) [Vendor MCP10 tools](/agentkit/connectors/privacymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/quizvideo.svg)](/agentkit/connectors/quizvideomcp/) [Quiz.Video MCPOAuth 2.1/DCR](/agentkit/connectors/quizvideomcp/) [Quiz.Video is an AI-powered platform for creating short-form quiz and flashcard videos. Transform topics, URLs, or documents into shareable quiz and...](/agentkit/connectors/quizvideomcp/) [Vendor MCP30 tools](/agentkit/connectors/quizvideomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/readai.svg)](/agentkit/connectors/readaimcp/) [Read AI MCPOAuth 2.1/DCR](/agentkit/connectors/readaimcp/) [Connect to Read AI to access your meeting intelligence — transcripts, summaries, action items, and insights from meetings, emails, and chats. Retrieve...](/agentkit/connectors/readaimcp/) [Vendor MCP4 tools](/agentkit/connectors/readaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/rize.svg)](/agentkit/connectors/rizemcp/) [Rize MCPOAuth 2.1/DCR](/agentkit/connectors/rizemcp/) [Connect to Rize MCP using OAuth 2.1 with MCP discovery and dynamic client registration. Access and analyze your time tracking data, projects, clients...](/agentkit/connectors/rizemcp/) [Vendor MCP72 tools](/agentkit/connectors/rizemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sanity.svg)](/agentkit/connectors/sanitymcp/) [Sanity MCPOAuth 2.1/DCR](/agentkit/connectors/sanitymcp/) [Connect to Sanity. Manage structured content, documents, datasets, schemas, releases, and media assets for headless CMS workflows.](/agentkit/connectors/sanitymcp/) [Vendor MCP45 tools](/agentkit/connectors/sanitymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/send.svg)](/agentkit/connectors/sendmcp/) [Send MCPOAuth 2.1/DCR](/agentkit/connectors/sendmcp/) [Connect to Send to create, edit, and share Claude-generated documents as polished web pages with engagement tracking, custom domains, and team asset...](/agentkit/connectors/sendmcp/) [Vendor MCP12 tools](/agentkit/connectors/sendmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/signwell.svg)](/agentkit/connectors/signwell/) [SignWellAPI Key](/agentkit/connectors/signwell/) [SignWell is an e-signature platform for sending, signing, and managing documents. Connect to create and send documents for signature, manage templates...](/agentkit/connectors/signwell/) [scalekit26 tools](/agentkit/connectors/signwell/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slack.svg)](/agentkit/connectors/slackmcp/) [Slack MCPOAuth 2.1](/agentkit/connectors/slackmcp/) [Connect to Slack MCP. Send and read messages, search channels and users, manage canvases, and react to messages across your Slack workspace.](/agentkit/connectors/slackmcp/) [Vendor MCP19 tools](/agentkit/connectors/slackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/sleekplan.svg)](/agentkit/connectors/sleekplanmcp/) [Sleekplan MCPOAuth 2.1/DCR](/agentkit/connectors/sleekplanmcp/) [Sleekplan is a customer feedback, feature request, and roadmap management platform.](/agentkit/connectors/sleekplanmcp/) [Vendor MCP60 tools](/agentkit/connectors/sleekplanmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/slite.svg)](/agentkit/connectors/slitemcp/) [Slite MCPOAuth 2.1/DCR](/agentkit/connectors/slitemcp/) [Connect to Slite MCP. Create and manage notes, channels, collections, and comments in Slite from AI workflows.](/agentkit/connectors/slitemcp/) [Vendor MCP40 tools](/agentkit/connectors/slitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/smartling.svg)](/agentkit/connectors/smartlingmcp/) [Smartling MCPOAuth 2.1/DCR](/agentkit/connectors/smartlingmcp/) [Connect to Smartling MCP to manage translation projects, jobs, files, and glossaries, and run machine translation and localization workflows from your AI...](/agentkit/connectors/smartlingmcp/) [Vendor MCP53 tools](/agentkit/connectors/smartlingmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/splice.svg)](/agentkit/connectors/splicemcp/) [Splice MCPOAuth 2.1/DCR](/agentkit/connectors/splicemcp/) [Connect to Splice MCP. Search the Splice sample catalog, create and update multi-track stacks, download audio assets, and generate arrangements from text...](/agentkit/connectors/splicemcp/) [Vendor MCP6 tools](/agentkit/connectors/splicemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/swagger.svg)](/agentkit/connectors/swaggermcp/) [Swagger MCPOAuth 2.1/DCR](/agentkit/connectors/swaggermcp/) [Connect to Swagger MCP. Create and manage APIs, developer portals, and documentation in SwaggerHub from AI workflows.](/agentkit/connectors/swaggermcp/) [Vendor MCP26 tools](/agentkit/connectors/swaggermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tableau.svg)](/agentkit/connectors/tableau/) [TableauAPI Key](/agentkit/connectors/tableau/) [Connect to Tableau Cloud or Tableau Server to browse workbooks, views, and data sources, export visualizations, and query underlying data.](/agentkit/connectors/tableau/) [scalekit49 tools](/agentkit/connectors/tableau/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tactiq.svg)](/agentkit/connectors/tactiqmcp/) [Tactiq MCPOAuth 2.1/DCR](/agentkit/connectors/tactiqmcp/) [Tactiq captures and transcribes meetings in real time, turning conversations into AI-generated notes, summaries, and action items.](/agentkit/connectors/tactiqmcp/) [Vendor MCP9 tools](/agentkit/connectors/tactiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tally.svg)](/agentkit/connectors/tallymcp/) [Tally MCPOAuth 2.1/DCR](/agentkit/connectors/tallymcp/) [Connect to Tally MCP. Create and edit forms, manage submissions, and update styling and logic in your Tally workspace from AI workflows.](/agentkit/connectors/tallymcp/) [Vendor MCP26 tools](/agentkit/connectors/tallymcp/) [![]()](/agentkit/connectors/ticktickmcp/) [TickTick MCPOAuth 2.1/DCR](/agentkit/connectors/ticktickmcp/) [Connect to TickTick MCP. Manage tasks, projects, habits, and focus sessions in your TickTick account from AI workflows.](/agentkit/connectors/ticktickmcp/) [Vendor MCP50 tools](/agentkit/connectors/ticktickmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/todoist.svg)](/agentkit/connectors/todoistmcp/) [Todoist MCPOAuth 2.1/DCR](/agentkit/connectors/todoistmcp/) [Connect to Todoist MCP. Manage tasks, projects, sections, labels, filters, goals, and reminders from your AI workflows.](/agentkit/connectors/todoistmcp/) [Vendor MCP47 tools](/agentkit/connectors/todoistmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/topcounsel.svg)](/agentkit/connectors/topcounselmcp/) [TopCounsel MCPOAuth 2.1/DCR](/agentkit/connectors/topcounselmcp/) [Connect to TopCounsel by The L Suite to search, shortlist, and compare peer-vetted outside counsel recommendations grounded in firsthand feedback from...](/agentkit/connectors/topcounselmcp/) [Vendor MCP1 tool](/agentkit/connectors/topcounselmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trello/) [TrelloOAuth 1.0a](/agentkit/connectors/trello/) [Connect to Trello. Manage boards, cards, lists, and team collaboration workflows](/agentkit/connectors/trello/) [scalekit36 tools](/agentkit/connectors/trello/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trellomcp/) [Trello MCPOAuth 2.1/DCR](/agentkit/connectors/trellomcp/) [Connect to Trello's official MCP server to manage boards, cards, lists, and team collaboration workflows directly from your AI workflows.](/agentkit/connectors/trellomcp/) [Vendor MCP15 tools](/agentkit/connectors/trellomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/typeform.svg)](/agentkit/connectors/typeformmcp/) [Typeform MCPOAuth 2.1/DCR](/agentkit/connectors/typeformmcp/) [Connect to Typeform MCP to create and manage forms, read responses, and manage workspaces, contacts, and webhooks directly from your AI workflows.](/agentkit/connectors/typeformmcp/) [Vendor MCP63 tools](/agentkit/connectors/typeformmcp/) [![](https://framerusercontent.com/images/Pl7PUhW6GIt6eumE6hy3eKACaA.png)](/agentkit/connectors/upstreammcp/) [Upstream MCPBearer Token](/agentkit/connectors/upstreammcp/) [Connect to Upstream MCP to access AI-assistant tools and workflows, including inbox management, directly from your AI workflows.](/agentkit/connectors/upstreammcp/) [Vendor MCP46 tools](/agentkit/connectors/upstreammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/vercel.svg)](/agentkit/connectors/vercelmcp/) [Vercel MCPOAuth 2.1](/agentkit/connectors/vercelmcp/) [Connect to Vercel MCP to manage deployments, projects, domains, environment variables, and team resources directly from your AI workflows.](/agentkit/connectors/vercelmcp/) [Vendor MCP34 tools](/agentkit/connectors/vercelmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/webflow.svg)](/agentkit/connectors/webflowmcp/) [Webflow MCPOAuth 2.1/DCR](/agentkit/connectors/webflowmcp/) [Connect to Webflow. Build and manage websites, pages, components, styles, assets, CMS collections, and site settings through the Webflow Designer and Data...](/agentkit/connectors/webflowmcp/) [Vendor MCP40 tools](/agentkit/connectors/webflowmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whimsical.svg)](/agentkit/connectors/whimsicalmcp/) [Whimsical MCPOAuth 2.1/DCR](/agentkit/connectors/whimsicalmcp/) [Connect to Whimsical MCP. Create and edit flowcharts, mind maps, wireframes, and docs, and manage boards, comments, and workspaces from your AI workflows.](/agentkit/connectors/whimsicalmcp/) [Vendor MCP18 tools](/agentkit/connectors/whimsicalmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/whop.svg)](/agentkit/connectors/whopmcp/) [Whop MCPOAuth 2.1/DCR](/agentkit/connectors/whopmcp/) [Whop is a platform for selling digital products, memberships, and communities.](/agentkit/connectors/whopmcp/) [Vendor MCP4 tools](/agentkit/connectors/whopmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/wix.svg)](/agentkit/connectors/wixmcp/) [Wix MCPOAuth 2.1/DCR](/agentkit/connectors/wixmcp/) [Connect to Wix MCP. Build and manage Wix sites, call REST APIs, search documentation, upload media, and suggest domains from your AI workflows.](/agentkit/connectors/wixmcp/) [Vendor MCP26 tools](/agentkit/connectors/wixmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/zapier.svg)](/agentkit/connectors/zapiermcp/) [Zapier MCPOAuth 2.1/DCR](/agentkit/connectors/zapiermcp/) [Connect to Zapier MCP to automate workflows and integrate with thousands of apps directly from your AI agent.](/agentkit/connectors/zapiermcp/) [Vendor MCP17 tools](/agentkit/connectors/zapiermcp/) ## Project Management [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtable/) [AirtableOAuth 2.0](/agentkit/connectors/airtable/) [Connect to Airtable. Manage databases, tables, records, and collaborate on structured data](/agentkit/connectors/airtable/) [scalekit26 tools](/agentkit/connectors/airtable/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/airtable.svg)](/agentkit/connectors/airtablemcp/) [Airtable MCPOAuth 2.1/DCR](/agentkit/connectors/airtablemcp/) [Connect to Airtable MCP. Manage bases, tables, records, views, fields, and automations from your AI workflows.](/agentkit/connectors/airtablemcp/) [Vendor MCP43 tools](/agentkit/connectors/airtablemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asana/) [AsanaOAuth 2.0](/agentkit/connectors/asana/) [Connect to Asana. Manage tasks, projects, teams, and workflow automation](/agentkit/connectors/asana/) [scalekit210 tools](/agentkit/connectors/asana/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/asana-n.svg)](/agentkit/connectors/asanamcp/) [Asana MCPOAuth 2.1](/agentkit/connectors/asanamcp/) [Connect to Asana MCP server to manage tasks, projects, and teams directly from your AI workflows.](/agentkit/connectors/asanamcp/) [Vendor MCP38 tools](/agentkit/connectors/asanamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/atlassian.svg)](/agentkit/connectors/atlassianmcp/) [Atlassian Rovo MCPOAuth 2.1/DCR](/agentkit/connectors/atlassianmcp/) [Connect to Atlassian Rovo MCP server to manage Jira issues, Confluence pages, and Compass components directly from your AI workflows.](/agentkit/connectors/atlassianmcp/) [Vendor MCP39 tools](/agentkit/connectors/atlassianmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/bonsai.svg)](/agentkit/connectors/bonsaimcp/) [Bonsai MCPOAuth 2.1/DCR](/agentkit/connectors/bonsaimcp/) [Connect to Bonsai, the all-in-one business management platform for freelancers and agencies. Manage projects, tasks, CRM contacts, deals, invoices, and...](/agentkit/connectors/bonsaimcp/) [Vendor MCP34 tools](/agentkit/connectors/bonsaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickup/) [ClickUpOAuth 2.0](/agentkit/connectors/clickup/) [Connect to ClickUp. Manage tasks, projects, workspaces, and team collaboration](/agentkit/connectors/clickup/) [scalekit99 tools](/agentkit/connectors/clickup/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clickup.svg)](/agentkit/connectors/clickupmcp/) [ClickUp MCPOAuth 2.1/DCR](/agentkit/connectors/clickupmcp/) [Connect to ClickUp MCP to manage tasks, projects, spaces, and workspaces directly from your AI workflows.](/agentkit/connectors/clickupmcp/) [Vendor MCP57 tools](/agentkit/connectors/clickupmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/confluence.svg)](/agentkit/connectors/confluence/) [ConfluenceOAuth 2.0](/agentkit/connectors/confluence/) [Connect to Confluence. Manage spaces, pages, content, and team collaboration](/agentkit/connectors/confluence/) [scalekit147 tools](/agentkit/connectors/confluence/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/dartai.svg)](/agentkit/connectors/dartaimcp/) [Dart AI MCPOAuth 2.1/DCR](/agentkit/connectors/dartaimcp/) [AI-native project management tool for task and document management with deep AI integration.](/agentkit/connectors/dartaimcp/) [Vendor MCP29 tools](/agentkit/connectors/dartaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fellowai.svg)](/agentkit/connectors/fellowaimcp/) [FellowAI MCPOAuth 2.1/DCR](/agentkit/connectors/fellowaimcp/) [Connect to Fellow.ai MCP to manage meeting notes, action items, agendas, and team collaboration workflows directly from your AI agent.](/agentkit/connectors/fellowaimcp/) [Vendor MCP7 tools](/agentkit/connectors/fellowaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fibery.svg)](/agentkit/connectors/fiberymcp/) [Fibery MCPOAuth 2.1/DCR](/agentkit/connectors/fiberymcp/) [Connect to Fibery MCP. Query, create, and update entities across your Fibery workspace using the Fibery API and AI assistant.](/agentkit/connectors/fiberymcp/) [Vendor MCP80 tools](/agentkit/connectors/fiberymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googletasks.svg)](/agentkit/connectors/googletasks/) [Google TasksOAuth 2.0](/agentkit/connectors/googletasks/) [Google Tasks is Google's task management service for creating and organizing to-do items and task lists, synced across Gmail, Calendar, and mobile devices.](/agentkit/connectors/googletasks/) [scalekit12 tools](/agentkit/connectors/googletasks/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/harvestapp.svg)](/agentkit/connectors/harvestmcp/) [Harvest MCPOAuth 2.1/DCR](/agentkit/connectors/harvestmcp/) [Harvest is a time tracking and invoicing tool that helps teams track time, manage projects, and create invoices.](/agentkit/connectors/harvestmcp/) [Vendor MCP36 tools](/agentkit/connectors/harvestmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jira.svg)](/agentkit/connectors/jira/) [JiraOAuth 2.0](/agentkit/connectors/jira/) [Connect to Jira. Manage issues, projects, workflows, and agile development processes](/agentkit/connectors/jira/) [scalekit374 tools](/agentkit/connectors/jira/) [![](https://wac-cdn.atlassian.com/dam/jcr:be09430e-3f78-4712-a953-ddcbe01ea541/jsd-icon.svg?cdnVersion=3478)](/agentkit/connectors/jiraservicemanagement/) [Jira Service ManagementOAuth 2.0](/agentkit/connectors/jiraservicemanagement/) [Connect to Jira Service Management. Manage customer requests, service desks, organizations, knowledge base articles, SLAs, and queues](/agentkit/connectors/jiraservicemanagement/) [scalekit72 tools](/agentkit/connectors/jiraservicemanagement/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linear.svg)](/agentkit/connectors/linear/) [LinearOAuth 2.0](/agentkit/connectors/linear/) [Connect to Linear. Manage issues, projects, sprints, and development workflows](/agentkit/connectors/linear/) [scalekit62 tools](/agentkit/connectors/linear/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/linear.svg)](/agentkit/connectors/linearmcp/) [Linear MCPOAuth 2.1/DCR](/agentkit/connectors/linearmcp/) [Connect to Linear's hosted MCP server to manage issues, projects, cycles, and comments directly from your AI workflows.](/agentkit/connectors/linearmcp/) [Vendor MCP63 tools](/agentkit/connectors/linearmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/loops.svg)](/agentkit/connectors/loopsmcp/) [Loops MCPOAuth 2.1/DCR](/agentkit/connectors/loopsmcp/) [Connect to Loops MCP. Create and manage loops and tasks, set priorities, track work queue stats, and ship completed loops from your AI workflows.](/agentkit/connectors/loopsmcp/) [Vendor MCP20 tools](/agentkit/connectors/loopsmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/mondaymcp/) [Monday MCPOAuth 2.1/DCR](/agentkit/connectors/mondaymcp/) [Connect to the monday.com MCP server to manage boards, items, columns, docs, and workflows directly from your AI agents.](/agentkit/connectors/mondaymcp/) [Vendor MCP94 tools](/agentkit/connectors/mondaymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/monday.svg)](/agentkit/connectors/monday/) [Monday.comOAuth 2.0](/agentkit/connectors/monday/) [Connect to Monday.com. Manage boards, tasks, workflows, teams, and project collaboration](/agentkit/connectors/monday/) [scalekit73 tools](/agentkit/connectors/monday/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/motion.svg)](/agentkit/connectors/motionmcp/) [Motion MCPOAuth 2.1/DCR](/agentkit/connectors/motionmcp/) [Connect to Motion MCP. Manage tasks, projects, workspaces, and schedules in the Motion AI-powered project management platform.](/agentkit/connectors/motionmcp/) [Vendor MCP14 tools](/agentkit/connectors/motionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notion/) [NotionOAuth 2.0](/agentkit/connectors/notion/) [Connect to Notion workspace. Create, edit pages, manage databases, and collaborate on content](/agentkit/connectors/notion/) [scalekit51 tools](/agentkit/connectors/notion/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/notion.svg)](/agentkit/connectors/notionmcp/) [Notion MCPOAuth 2.1/DCR](/agentkit/connectors/notionmcp/) [Connect to Notion MCP. Create and update pages, databases, comments, and views from your AI workflows.](/agentkit/connectors/notionmcp/) [Vendor MCP28 tools](/agentkit/connectors/notionmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plane.svg)](/agentkit/connectors/planemcp/) [Plane MCPOAuth 2.1/DCR](/agentkit/connectors/planemcp/) [Connect to Plane MCP. Manage projects, work items, cycles, modules, epics, and initiatives in your Plane workspace from AI workflows.](/agentkit/connectors/planemcp/) [Vendor MCP109 tools](/agentkit/connectors/planemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/pylon.svg)](/agentkit/connectors/pylonmcp/) [Pylon MCPOAuth 2.1/DCR](/agentkit/connectors/pylonmcp/) [Connect to Pylon MCP. Manage customer issues, accounts, projects, milestones, and tasks from your AI workflows.](/agentkit/connectors/pylonmcp/) [Vendor MCP31 tools](/agentkit/connectors/pylonmcp/) [![]()](/agentkit/connectors/ticktickmcp/) [TickTick MCPOAuth 2.1/DCR](/agentkit/connectors/ticktickmcp/) [Connect to TickTick MCP. Manage tasks, projects, habits, and focus sessions in your TickTick account from AI workflows.](/agentkit/connectors/ticktickmcp/) [Vendor MCP50 tools](/agentkit/connectors/ticktickmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/todoist.svg)](/agentkit/connectors/todoistmcp/) [Todoist MCPOAuth 2.1/DCR](/agentkit/connectors/todoistmcp/) [Connect to Todoist MCP. Manage tasks, projects, sections, labels, filters, goals, and reminders from your AI workflows.](/agentkit/connectors/todoistmcp/) [Vendor MCP47 tools](/agentkit/connectors/todoistmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trello/) [TrelloOAuth 1.0a](/agentkit/connectors/trello/) [Connect to Trello. Manage boards, cards, lists, and team collaboration workflows](/agentkit/connectors/trello/) [scalekit36 tools](/agentkit/connectors/trello/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/trello_n.svg)](/agentkit/connectors/trellomcp/) [Trello MCPOAuth 2.1/DCR](/agentkit/connectors/trellomcp/) [Connect to Trello's official MCP server to manage boards, cards, lists, and team collaboration workflows directly from your AI workflows.](/agentkit/connectors/trellomcp/) [Vendor MCP15 tools](/agentkit/connectors/trellomcp/) ## Search [![](https://akta.pro/favicon.ico?favicon.0_ooe5s20rw4w.ico)](/agentkit/connectors/aktapro/) [Akta ProAPI Key](/agentkit/connectors/aktapro/) [Connect to Akta Pro to search and monitor company news signals, including sentiment, entities, and industry classification, for sales and market...](/agentkit/connectors/aktapro/) [scalekit1 tool](/agentkit/connectors/aktapro/) [![](https://akta.pro/favicon.ico?favicon.0_ooe5s20rw4w.ico)](/agentkit/connectors/aktapromcp/) [Akta Pro MCPAPI Key](/agentkit/connectors/aktapromcp/) [Connect to Akta Pro MCP to search company news signals, check account status, and access sales intelligence tools directly from your AI agents.](/agentkit/connectors/aktapromcp/) [Vendor MCP17 tools](/agentkit/connectors/aktapromcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/alphaxiv.svg)](/agentkit/connectors/alphaxivmcp/) [AlphaXiv MCPOAuth 2.1/DCR](/agentkit/connectors/alphaxivmcp/) [Connect to AlphaXiv MCP to search and retrieve arXiv research papers, abstracts, authors, and citations from your AI workflows.](/agentkit/connectors/alphaxivmcp/) [Vendor MCP18 tools](/agentkit/connectors/alphaxivmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biorendermcp.svg)](/agentkit/connectors/biorendermcp/) [Bio Render MCPOAuth 2.1/DCR](/agentkit/connectors/biorendermcp/) [Connect to BioRender MCP. Search BioRender's scientific icon and figure template libraries to build publication-ready biological illustrations.](/agentkit/connectors/biorendermcp/) [Vendor MCP2 tools](/agentkit/connectors/biorendermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/biomni.svg)](/agentkit/connectors/biomnimcp/) [Biomni MCPOAuth 2.1/DCR](/agentkit/connectors/biomnimcp/) [Connect to Biomni MCP by phylo.bio, an AI biomedical research assistant. Analyze life-sciences data, interpret genomic variants, query curated databases...](/agentkit/connectors/biomnimcp/) [Vendor MCP12 tools](/agentkit/connectors/biomnimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/brave.svg)](/agentkit/connectors/brave/) [Brave SearchAPI Key](/agentkit/connectors/brave/) [Connect to Brave Search to perform web, image, video, and news searches with privacy-focused results, plus AI-powered suggestions and spellcheck.](/agentkit/connectors/brave/) [scalekit18 tools](/agentkit/connectors/brave/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/candid.svg)](/agentkit/connectors/candidmcp/) [Candid MCPOAuth 2.1/DCR](/agentkit/connectors/candidmcp/) [Connect to Candid MCP. Search nonprofit organizations, explore philanthropic data, and classify social sector activities using Candid's knowledge base.](/agentkit/connectors/candidmcp/) [Vendor MCP6 tools](/agentkit/connectors/candidmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/crustdata.svg)](/agentkit/connectors/crustdatamcp/) [Crustdata MCPOAuth 2.1/DCR](/agentkit/connectors/crustdatamcp/) [People and company intelligence platform for candidate sourcing, sales prospecting, and talent intelligence. Provides real-time data on professionals...](/agentkit/connectors/crustdatamcp/) [Vendor MCP68 tools](/agentkit/connectors/crustdatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/exa/) [ExaAPI Key](/agentkit/connectors/exa/) [Connect to Exa to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, run in-depth...](/agentkit/connectors/exa/) [scalekit21 tools](/agentkit/connectors/exa/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/exa.svg)](/agentkit/connectors/examcp/) [Exa MCPAPI Key](/agentkit/connectors/examcp/) [Connect to Exa MCP to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, and run...](/agentkit/connectors/examcp/) [Vendor MCP2 tools](/agentkit/connectors/examcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fever.svg)](/agentkit/connectors/fevermcp/) [Fever MCPOAuth 2.1/DCR](/agentkit/connectors/fevermcp/) [Fever is a live entertainment discovery platform. This MCP connector gives AI assistants direct access to Fever's global event catalog — search events by...](/agentkit/connectors/fevermcp/) [Vendor MCP2 tools](/agentkit/connectors/fevermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/firecrawl.svg)](/agentkit/connectors/firecrawlmcp/) [Firecrawl MCPBearer Token](/agentkit/connectors/firecrawlmcp/) [Connect to Firecrawl MCP. Scrape, crawl, search, extract structured data, and monitor websites using Firecrawl's AI-powered web scraping API.](/agentkit/connectors/firecrawlmcp/) [Vendor MCP26 tools](/agentkit/connectors/firecrawlmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/googlesearch.svg)](/agentkit/connectors/googlesearchconsole/) [Google Search ConsoleOAuth 2.0](/agentkit/connectors/googlesearchconsole/) [Google Search Console (the Search Console API, formerly Webmaster Tools API) lets you monitor and manage a site's presence in Google Search results —...](/agentkit/connectors/googlesearchconsole/) [scalekit10 tools](/agentkit/connectors/googlesearchconsole/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/greptile.svg)](/agentkit/connectors/greptilmcp/) [Greptile MCPOAuth 2.1/DCR](/agentkit/connectors/greptilmcp/) [AI-powered code search and understanding API that indexes GitHub and GitLab repositories, enabling natural language queries over codebases.](/agentkit/connectors/greptilmcp/) [Vendor MCP16 tools](/agentkit/connectors/greptilmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/legaldatahunter.svg)](/agentkit/connectors/legaldatahuntermcp/) [Legal Data Hunter MCPOAuth 2.1/DCR](/agentkit/connectors/legaldatahuntermcp/) [Connect to Legal Data Hunter MCP. Search and explore indexed legal data sources worldwide, tracking case law, courts, dockets, and legal data coverage...](/agentkit/connectors/legaldatahuntermcp/) [Vendor MCP7 tools](/agentkit/connectors/legaldatahuntermcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mobbins.svg)](/agentkit/connectors/mobbinmcp/) [Mobbin MCPOAuth 2.1/DCR](/agentkit/connectors/mobbinmcp/) [Connect to Mobbin's MCP server to search real-world UI and UX design references from mobile apps, web apps, and websites using natural language. Returns...](/agentkit/connectors/mobbinmcp/) [Vendor MCP3 tools](/agentkit/connectors/mobbinmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/mtnewswires.svg)](/agentkit/connectors/mtnewswiresmcp/) [MT Newswires MCPOAuth 2.1/DCR](/agentkit/connectors/mtnewswiresmcp/) [Connect to the MT Newswires MCP server on viaNexus to search and retrieve real-time, low-latency financial news across equities, fixed income...](/agentkit/connectors/mtnewswiresmcp/) [Vendor MCP6 tools](/agentkit/connectors/mtnewswiresmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/nimble.svg)](/agentkit/connectors/nimblemcp/) [Nimble MCPBearer Token](/agentkit/connectors/nimblemcp/) [Connect to Nimble MCP. Search the web across multiple engines, extract content from any URL, crawl websites at scale, discover all URLs on a site, and run...](/agentkit/connectors/nimblemcp/) [Vendor MCP31 tools](/agentkit/connectors/nimblemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scrapfly.svg)](/agentkit/connectors/scarpflymcp/) [Scarpfly MCPOAuth 2.1/DCR](/agentkit/connectors/scarpflymcp/) [Connect to Scrapfly MCP. Scrape web pages, take screenshots, and control a cloud browser with anti-bot bypass, JS rendering, and proxy support.](/agentkit/connectors/scarpflymcp/) [Vendor MCP31 tools](/agentkit/connectors/scarpflymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scholargateway.svg)](/agentkit/connectors/scholargateway/) [Scholar Gateway MCPOAuth 2.1/DCR](/agentkit/connectors/scholargateway/) [Connect to Scholar Gateway to search Wiley's peer-reviewed academic literature — 8M+ articles from 2,000+ journals spanning sciences, healthcare...](/agentkit/connectors/scholargateway/) [scalekit1 tool](/agentkit/connectors/scholargateway/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/scite.svg)](/agentkit/connectors/scitemcp/) [Scite MCPOAuth 2.1/DCR](/agentkit/connectors/scitemcp/) [Connect to Scite's MCP server to search scientific literature, patents, clinical trials, grants, and FDA drug/device safety data, and manage citation...](/agentkit/connectors/scitemcp/) [Vendor MCP25 tools](/agentkit/connectors/scitemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadata/) [SupadataAPI Key](/agentkit/connectors/supadata/) [Connect with Supadata to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadata/) [scalekit21 tools](/agentkit/connectors/supadata/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadatamcp/) [Supadata MCPOAuth 2.1/DCR](/agentkit/connectors/supadatamcp/) [Connect with Supadata MCP to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadatamcp/) [Vendor MCP9 tools](/agentkit/connectors/supadatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synapse.svg)](/agentkit/connectors/synapsemcp/) [Synapse MCPOAuth 2.1/DCR](/agentkit/connectors/synapsemcp/) [Connect to the Synapse MCP server (Sage Bionetworks) to explore Synapse entities, annotations, provenance, and project structure, and to search...](/agentkit/connectors/synapsemcp/) [Vendor MCP48 tools](/agentkit/connectors/synapsemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/synthesize-bio.svg)](/agentkit/connectors/synthesizebiomcp/) [Synthesize Bio MCPOAuth 2.1/DCR](/agentkit/connectors/synthesizebiomcp/) [Connect to Synthesize Bio MCP. Run differential gene expression analysis, resolve sample metadata, and retrieve results and raw counts data from your AI...](/agentkit/connectors/synthesizebiomcp/) [Vendor MCP5 tools](/agentkit/connectors/synthesizebiomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tango.svg)](/agentkit/connectors/tangomcp/) [Tango MCPAPI Key](/agentkit/connectors/tangomcp/) [Connect to Tango MCP by makegov to search federal contracts, opportunities, vehicles, organizations, and protests, and pull competitive...](/agentkit/connectors/tangomcp/) [Vendor MCP5 tools](/agentkit/connectors/tangomcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tavily.svg)](/agentkit/connectors/tavilymcp/) [Tavily MCPOAuth 2.1/DCR](/agentkit/connectors/tavilymcp/) [Connect to Tavily MCP. Search the web, crawl websites, extract content, map site structure, and run deep research using Tavily's AI-powered search API.](/agentkit/connectors/tavilymcp/) [Vendor MCP5 tools](/agentkit/connectors/tavilymcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/topcounsel.svg)](/agentkit/connectors/topcounselmcp/) [TopCounsel MCPOAuth 2.1/DCR](/agentkit/connectors/topcounselmcp/) [Connect to TopCounsel by The L Suite to search, shortlist, and compare peer-vetted outside counsel recommendations grounded in firsthand feedback from...](/agentkit/connectors/topcounselmcp/) [Vendor MCP1 tool](/agentkit/connectors/topcounselmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/you.svg)](/agentkit/connectors/youmcp/) [You.com MCPBearer Token](/agentkit/connectors/youmcp/) [Connect to You.com MCP. Search the web, research topics with cited sources, and extract full page content using You.com's AI-powered search and research...](/agentkit/connectors/youmcp/) [Vendor MCP6 tools](/agentkit/connectors/youmcp/) ## Transcription [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/chorus.svg)](/agentkit/connectors/chorus/) [ChorusBasic Auth](/agentkit/connectors/chorus/) [Connect to Chorus.ai to sync calls, transcripts, conversation intelligence, and analytics.](/agentkit/connectors/chorus/) [scalekit9 tools](/agentkit/connectors/chorus/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/circleback.svg)](/agentkit/connectors/circlebackmcp/) [Circleback MCPOAuth 2.1/DCR](/agentkit/connectors/circlebackmcp/) [Circleback is an AI meeting notes and conversation intelligence platform. The Circleback MCP server provides a standardized interface that allows any...](/agentkit/connectors/circlebackmcp/) [Vendor MCP11 tools](/agentkit/connectors/circlebackmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/clari.svg)](/agentkit/connectors/clari_copilot/) [Clari CopilotAPI Key](/agentkit/connectors/clari_copilot/) [Connect to Clari Copilot for sales call transcripts, analytics, call data, and insights.](/agentkit/connectors/clari_copilot/) [scalekitComing soon](/agentkit/connectors/clari_copilot/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/deepgram.svg)](/agentkit/connectors/deepgrammcp/) [Deepgram MCPOAuth 2.1/DCR](/agentkit/connectors/deepgrammcp/) [Connect to Deepgram MCP. Transcribe audio, generate speech, and manage transcription projects using Deepgram's AI-powered speech recognition API.](/agentkit/connectors/deepgrammcp/) [Vendor MCP1 tool](/agentkit/connectors/deepgrammcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/diarize.svg)](/agentkit/connectors/diarize/) [DiarizeBearer Token](/agentkit/connectors/diarize/) [Connect to Diarize to transcribe and diarize audio and video content from YouTube, X, Instagram, and TikTok. Submit transcription jobs and retrieve...](/agentkit/connectors/diarize/) [scalekit3 tools](/agentkit/connectors/diarize/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathom/) [FathomAPI Key](/agentkit/connectors/fathom/) [Connect to Fathom AI meeting assistant. Record, transcribe, and summarize meetings with AI-powered insights](/agentkit/connectors/fathom/) [scalekit11 tools](/agentkit/connectors/fathom/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fathom.svg)](/agentkit/connectors/fathommcp/) [Fathom MCPOAuth 2.1/DCR](/agentkit/connectors/fathommcp/) [Connect to Fathom MCP to access AI meeting notes, summaries, transcripts, and recordings from your AI workflows.](/agentkit/connectors/fathommcp/) [Vendor MCP9 tools](/agentkit/connectors/fathommcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/fireflies.svg)](/agentkit/connectors/firefliesmcp/) [Fireflies MCPOAuth 2.1/DCR](/agentkit/connectors/firefliesmcp/) [Connect to Fireflies MCP. Search meeting transcripts, fetch recordings, manage channels, create soundbites, and retrieve analytics from your AI workflows.](/agentkit/connectors/firefliesmcp/) [Vendor MCP20 tools](/agentkit/connectors/firefliesmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gong/) [GongOAuth 2.0](/agentkit/connectors/gong/) [Connect with Gong to sync calls, transcripts, insights, coaching and CRM activity](/agentkit/connectors/gong/) [scalekit49 tools](/agentkit/connectors/gong/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/gong.svg)](/agentkit/connectors/gongmcp/) [Gong MCPOAuth 2.1](/agentkit/connectors/gongmcp/) [Connect with Gong MCP to access calls, transcripts, insights, coaching, and sales engagement data via the Model Context Protocol](/agentkit/connectors/gongmcp/) [Vendor MCP3 tools](/agentkit/connectors/gongmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grain/) [GrainBearer Token](/agentkit/connectors/grain/) [Grain's REST API for managing meeting recordings, transcripts, webhooks, and workspace data. Search and retrieve recordings and transcripts, upload and...](/agentkit/connectors/grain/) [scalekit19 tools](/agentkit/connectors/grain/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/grain.svg)](/agentkit/connectors/grainmcp/) [Grain MCPOAuth 2.1/DCR](/agentkit/connectors/grainmcp/) [Grain is a meeting recording and intelligence platform. Use this connector to search and retrieve meeting recordings, transcripts, notes, action items...](/agentkit/connectors/grainmcp/) [Vendor MCP41 tools](/agentkit/connectors/grainmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granola/) [GranolaBearer Token](/agentkit/connectors/granola/) [Connect to Granola to access AI-generated meeting notes, summaries, transcripts, and attendee data from your workspace. Granola automatically records and...](/agentkit/connectors/granola/) [scalekit9 tools](/agentkit/connectors/granola/) [![](https://cdn.scalekit.cloud/sk-connect/assets/provider-icons/granola.svg)](/agentkit/connectors/granolamcp/) [Granola MCPOAuth 2.1/DCR](/agentkit/connectors/granolamcp/) [Connect to Granola MCP using OAuth 2.1 with MCP discovery and dynamic client registration.](/agentkit/connectors/granolamcp/) [Vendor MCP6 tools](/agentkit/connectors/granolamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/happyscribe.svg)](/agentkit/connectors/happyscribemcp/) [HappyScribe MCPOAuth 2.1/DCR](/agentkit/connectors/happyscribemcp/) [HappyScribe is an AI-powered transcription and translation service. Connect your HappyScribe account to search transcripts, generate meeting summaries...](/agentkit/connectors/happyscribemcp/) [Vendor MCP39 tools](/agentkit/connectors/happyscribemcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/jiminny.svg)](/agentkit/connectors/jiminny/) [JiminnyBearer Token](/agentkit/connectors/jiminny/) [Connect with Jiminny to access call recordings, transcripts, coaching insights, and conversation intelligence data.](/agentkit/connectors/jiminny/) [scalekit27 tools](/agentkit/connectors/jiminny/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/lilt.svg)](/agentkit/connectors/liltmcp/) [LILT MCPOAuth 2.1/DCR](/agentkit/connectors/liltmcp/) [LILT is an enterprise translation platform that combines AI speed with human expertise to deliver accurate, domain-specific translations at scale. This...](/agentkit/connectors/liltmcp/) [Vendor MCP9 tools](/agentkit/connectors/liltmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/momentum..svg)](/agentkit/connectors/momentum/) [MomentumAPI Key](/agentkit/connectors/momentum/) [Connect to Momentum, the AI-powered revenue intelligence platform. Retrieve meetings with attendee and transcript details, ingest and remap meetings, run...](/agentkit/connectors/momentum/) [scalekit8 tools](/agentkit/connectors/momentum/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/otterai.svg)](/agentkit/connectors/otteraimcp/) [OtterAI MCPOAuth 2.1/DCR](/agentkit/connectors/otteraimcp/) [Connect to OtterAI MCP. Search meeting recordings, fetch full transcripts, and retrieve user account info from your AI workflows.](/agentkit/connectors/otteraimcp/) [Vendor MCP3 tools](/agentkit/connectors/otteraimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/plaud.svg)](/agentkit/connectors/plaudmcp/) [Plaud MCPOAuth 2.1/DCR](/agentkit/connectors/plaudmcp/) [Connect to Plaud MCP. Browse your Plaud recordings, read AI-generated notes, and pull timestamped transcripts with speaker labels into your AI workflows.](/agentkit/connectors/plaudmcp/) [Vendor MCP5 tools](/agentkit/connectors/plaudmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/proshortai.svg)](/agentkit/connectors/proshortai/) [ProShort AIAPI Key](/agentkit/connectors/proshortai/) [Connect to ProShort AI to search and retrieve AI-analyzed sales call recordings, transcripts, and summaries.](/agentkit/connectors/proshortai/) [scalekit5 tools](/agentkit/connectors/proshortai/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/readai.svg)](/agentkit/connectors/readaimcp/) [Read AI MCPOAuth 2.1/DCR](/agentkit/connectors/readaimcp/) [Connect to Read AI to access your meeting intelligence — transcripts, summaries, action items, and insights from meetings, emails, and chats. Retrieve...](/agentkit/connectors/readaimcp/) [Vendor MCP4 tools](/agentkit/connectors/readaimcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/supadata.svg)](/agentkit/connectors/supadatamcp/) [Supadata MCPOAuth 2.1/DCR](/agentkit/connectors/supadatamcp/) [Connect with Supadata MCP to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI.](/agentkit/connectors/supadatamcp/) [Vendor MCP9 tools](/agentkit/connectors/supadatamcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/tactiq.svg)](/agentkit/connectors/tactiqmcp/) [Tactiq MCPOAuth 2.1/DCR](/agentkit/connectors/tactiqmcp/) [Tactiq captures and transcribes meetings in real time, turning conversations into AI-generated notes, summaries, and action items.](/agentkit/connectors/tactiqmcp/) [Vendor MCP9 tools](/agentkit/connectors/tactiqmcp/) [![](https://cdn.scalekit.com/sk-connect/assets/provider-icons/weflow.svg)](/agentkit/connectors/weflow/) [WeflowBearer Token](/agentkit/connectors/weflow/) [Connect to Weflow's Public API to read call and meeting recordings and their conversation intelligence data — transcripts, comments, clips, interaction...](/agentkit/connectors/weflow/) [scalekit11 tools](/agentkit/connectors/weflow/) No connectors or tools match your search. --- # DOCUMENT BOUNDARY --- # Activepieces MCP connector > Connect to Activepieces MCP to trigger and manage no-code automation flows directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'activepiecesmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Activepieces MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'activepiecesmcp_ap_change_flow_status', 25 toolInput: { flowId: 'YOUR_FLOWID', status: 'YOUR_STATUS' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "activepiecesmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Activepieces MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"flowId":"YOUR_FLOWID","status":"YOUR_STATUS"}, 27 tool_name="activepiecesmcp_ap_change_flow_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search ap** — Find piece triggers (the event that starts a flow) by natural-language description of when the flow should run (e.g * **Read ap** — Read the full untruncated settings of any step, including the trigger: piece input, action/trigger name, loop items, router branches, and error handling options * **Config ap validate step** — Validate a step configuration before applying it * **Flow ap validate, ap test, ap rename** — Validate a flow for structural issues without publishing * **Update ap** — Set or update the trigger for a flow * **Step ap test, ap add** — Test a single step within a flow ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Adobe Marketing Agent MCP connector > Connect to Adobe Marketing Cloud. Manage campaigns, analytics, and journeys using a natural-language AI assistant. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Adobe Marketing Agent MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'adobemarketingagentmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Adobe Marketing Agent MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'adobemarketingagentmcp_core-context-management-widget', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "adobemarketingagentmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Adobe Marketing Agent MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="adobemarketingagentmcp_core-context-management-widget", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Preferences core-user** — Read or clear the user’s persisted preferences including sandbox, dataview, org, and region settings * **Dataview core-switch sandbox, core-set** — Update the active sandbox and/or dataview for the session in a single call * **Org core-switch** — Switch to a different Adobe organization by exchanging the current IMS token * **Sandbox core-set** — Set the active Adobe Experience Platform sandbox for the current session * **Feedback core-provide** — Submit user feedback about the AI assistant experience; automatically classifies sentiment and calls the feedback API * **Decision core-plan completion** — Submit the user’s approval or rejection for a pending plan before it is executed ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Send a query to the Adobe Marketing AI assistant Use `adobemarketingagentmcp_adobe-marketing-agent-mcp-widget` to ask questions about your campaigns, audiences, journeys, and Analytics data in plain English. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'adobemarketingagentmcp', 3 identifier: 'user_123', 4 toolName: 'adobemarketingagentmcp_adobe-marketing-agent-mcp-widget', 5 toolInput: { 6 query: 'What are my top performing audience segments this month?', 7 }, 8 }); 9 console.log(result); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="adobemarketingagentmcp", 3 identifier="user_123", 4 tool_name="adobemarketingagentmcp_adobe-marketing-agent-mcp-widget", 5 tool_input={ 6 "query": "What are my top performing audience segments this month?", 7 }, 8 ) 9 print(result) ``` ### Switch sandbox and dataview Use `adobemarketingagentmcp_core-switch_sandbox_dataview` to update the active Adobe Experience Platform sandbox and Customer Journey Analytics dataview in a single call. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'adobemarketingagentmcp', 3 identifier: 'user_123', 4 toolName: 'adobemarketingagentmcp_core-switch_sandbox_dataview', 5 toolInput: { 6 sandboxName: 'prod', 7 dataviewName: 'My Analytics View', 8 }, 9 }); 10 console.log(result); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="adobemarketingagentmcp", 3 identifier="user_123", 4 tool_name="adobemarketingagentmcp_core-switch_sandbox_dataview", 5 tool_input={ 6 "sandboxName": "prod", 7 "dataviewName": "My Analytics View", 8 }, 9 ) 10 print(result) ``` ### Poll an async task Some Adobe Marketing operations run asynchronously. Submit a query with `execution_mode: "async"`, then poll with `adobemarketingagentmcp_core-get_task` until the task completes. * Node.js ```typescript 1 // Step 1 — submit async query 2 const submitted = await actions.executeTool({ 3 connectionName: 'adobemarketingagentmcp', 4 identifier: 'user_123', 5 toolName: 'adobemarketingagentmcp_adobe-marketing-agent-mcp-widget', 6 toolInput: { 7 query: 'Generate a full audience overlap report', 8 execution_mode: 'async', 9 }, 10 }); 11 const taskId = submitted.data?.task_id; 12 13 // Step 2 — poll until complete 14 let cursor = 0; 15 while (true) { 16 const status = await actions.executeTool({ 17 connectionName: 'adobemarketingagentmcp', 18 identifier: 'user_123', 19 toolName: 'adobemarketingagentmcp_core-get_task', 20 toolInput: { task_id: taskId, cursor }, 21 }); 22 cursor = status.data?.cursor ?? cursor; 23 if (status.data?.status === 'completed') { 24 console.log(status.data.result); 25 break; 26 } 27 await new Promise(r => setTimeout(r, 2000)); 28 } ``` * Python ```python 1 import time 2 3 # Step 1 — submit async query 4 submitted = actions.execute_tool( 5 connection_name="adobemarketingagentmcp", 6 identifier="user_123", 7 tool_name="adobemarketingagentmcp_adobe-marketing-agent-mcp-widget", 8 tool_input={ 9 "query": "Generate a full audience overlap report", 10 "execution_mode": "async", 11 }, 12 ) 13 task_id = submitted.data.get("task_id") 14 15 # Step 2 — poll until complete 16 cursor = 0 17 while True: 18 status = actions.execute_tool( 19 connection_name="adobemarketingagentmcp", 20 identifier="user_123", 21 tool_name="adobemarketingagentmcp_core-get_task", 22 tool_input={"task_id": task_id, "cursor": cursor}, 23 ) 24 cursor = status.data.get("cursor", cursor) 25 if status.data.get("status") == "completed": 26 print(status.data.get("result")) 27 break 28 time.sleep(2) ``` ### Read and clear user preferences User preferences (sandbox, dataview, org, region) persist for 90 days. Use `adobemarketingagentmcp_core-user_preferences` to read or clear them. * Node.js ```typescript 1 // Read current preferences 2 const prefs = await actions.executeTool({ 3 connectionName: 'adobemarketingagentmcp', 4 identifier: 'user_123', 5 toolName: 'adobemarketingagentmcp_core-user_preferences', 6 toolInput: { action: 'get' }, 7 }); 8 console.log(prefs.data); 9 10 // Clear all preferences 11 await actions.executeTool({ 12 connectionName: 'adobemarketingagentmcp', 13 identifier: 'user_123', 14 toolName: 'adobemarketingagentmcp_core-user_preferences', 15 toolInput: { action: 'clear' }, 16 }); ``` * Python ```python 1 # Read current preferences 2 prefs = actions.execute_tool( 3 connection_name="adobemarketingagentmcp", 4 identifier="user_123", 5 tool_name="adobemarketingagentmcp_core-user_preferences", 6 tool_input={"action": "get"}, 7 ) 8 print(prefs.data) 9 10 # Clear all preferences 11 actions.execute_tool( 12 connection_name="adobemarketingagentmcp", 13 identifier="user_123", 14 tool_name="adobemarketingagentmcp_core-user_preferences", 15 tool_input={"action": "clear"}, 16 ) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # AdvancedMD connector > AdvancedMD is a cloud-based medical practice management and electronic health record (EHR) platform. This connector uses the SMART on FHIR authorization... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your AdvancedMD credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read clinical records** — retrieve a Patient, Practitioner, Organization, Encounter, Condition, Observation, AllergyIntolerance, Immunization, MedicationRequest, DiagnosticReport, Procedure, or Appointment by its FHIR logical ID * **Search clinical records** — find any supported FHIR resource using parameters like patient, clinical status, category, date, and code * **Create clinical records** — add new records for any of the twelve supported FHIR resource types * **Update clinical records** — modify an existing FHIR resource by its logical ID * **Delete clinical records** — remove a FHIR resource by its logical ID * **Retrieve everything for a patient** — invoke the `$everything` operation on a Patient to pull all associated clinical resources in a single Bundle ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Adzviser MCP connector > Connect to Adzviser MCP to query real-time marketing analytics across 46+ platforms - Google Ads, Facebook Ads, GA4, TikTok, LinkedIn, and more - from a... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Adzviser MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'adzvisermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Adzviser MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'adzvisermcp_list_countries_fb_ad_library', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "adzvisermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Adzviser MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="adzvisermcp_list_countries_fb_ad_library", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List metrics and breakdowns yahoo dsp, metrics and breakdowns tiktok shop, metrics and breakdowns mntn** — Get the list of selectable Yahoo DSP metrics like Impressions, Clicks, Spend, and breakdowns like Campaign, Ad group, and Creative etc * **Data retrieve reporting** — Retrieve real-time reporting data from marketing channels like Google Ads, Facebook Ads and Google Analytics ## Common workflows [Section titled “Common workflows”](#common-workflows) ### List workspaces Use `adzvisermcp_list_workspace` to retrieve the workspaces the user has configured, along with their connected ad platform accounts. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'adzvisermcp', 3 identifier: 'user_123', 4 toolName: 'adzvisermcp_list_workspace', 5 toolInput: {}, 6 }); 7 console.log(result); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="adzvisermcp", 3 identifier="user_123", 4 tool_name="adzvisermcp_list_workspace", 5 tool_input={}, 6 ) 7 print(result) ``` ### Discover available metrics for a platform Before querying data, call a `list_metrics_and_breakdowns_*` tool to discover valid metric and breakdown names for your target platform. * Node.js ```typescript 1 // Discover Google Ads metrics and breakdowns 2 const fields = await actions.executeTool({ 3 connectionName: 'adzvisermcp', 4 identifier: 'user_123', 5 toolName: 'adzvisermcp_list_metrics_and_breakdowns_google_ads', 6 toolInput: {}, 7 }); 8 console.log(fields); ``` * Python ```python 1 # Discover Google Ads metrics and breakdowns 2 fields = actions.execute_tool( 3 connection_name="adzvisermcp", 4 identifier="user_123", 5 tool_name="adzvisermcp_list_metrics_and_breakdowns_google_ads", 6 tool_input={}, 7 ) 8 print(fields) ``` ### Retrieve reporting data across platforms Use `adzvisermcp_retrieve_reporting_data` to pull structured analytics from one or more connected platforms. Pass an `adzviser_request` object to specify metrics, breakdowns, date ranges, and filters. Most use cases work without this parameter — Adzviser auto-fetches data from all connected accounts. * Node.js ```typescript 1 const report = await actions.executeTool({ 2 connectionName: 'adzvisermcp', 3 identifier: 'user_123', 4 toolName: 'adzvisermcp_retrieve_reporting_data', 5 toolInput: { 6 adzviser_request: { 7 google_ads_request: { 8 metrics: ['Clicks', 'Impressions', 'Cost'], 9 breakdowns: ['Campaign Name'], 10 date_ranges: [{ start_date: '2024-01-01', end_date: '2024-01-31' }], 11 }, 12 }, 13 }, 14 }); 15 console.log(report); ``` * Python ```python 1 report = actions.execute_tool( 2 connection_name="adzvisermcp", 3 identifier="user_123", 4 tool_name="adzvisermcp_retrieve_reporting_data", 5 tool_input={ 6 "adzviser_request": { 7 "google_ads_request": { 8 "metrics": ["Clicks", "Impressions", "Cost"], 9 "breakdowns": ["Campaign Name"], 10 "date_ranges": [{"start_date": "2024-01-01", "end_date": "2024-01-31"}], 11 }, 12 }, 13 }, 14 ) 15 print(report) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Affinda MCP connector > AI-powered document processing platform that extracts, validates, and integrates structured data from invoices, resumes, contracts, and custom document... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'affindamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Affinda MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'affindamcp_list_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "affindamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Affinda MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="affindamcp_list_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tag, workspace, validation rule** — Rename a tag * **Documents remove tag from, add tag to, reject** — Take a tag off one or more documents * **List tags, workspaces, validation rules** — List the tags defined in a workspace * **Get document page images, workspace details, workspace** — View a document’s pages as rendered images, to see the actual document rather than just OCR text * **Delete tag, validation rule, matching criterion** — Delete a tag from its workspace * **Create tag, workspace, validation run** — Create a new tag in a workspace ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Affinity connector > Connect to Affinity relationship intelligence CRM to manage deal flow, relationships, pipeline opportunities, and network connections for private capital... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'affinity' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'affinity_list_lists', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "affinity" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="affinity_list_lists", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update v2, person** — Updates a single field’s value on a person * **Search v2, persons** — Searches persons matching a combination of filters, sorts, and a search term * **List v2** — Paginates through persons in your Affinity organization using the V2 API * **Get v2** — Retrieves a single field’s value on a person * **Delete note, person, organization** — Permanently delete a note from Affinity * **Create person, organization, note** — Create a new person record in Affinity ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Agency Analytics MCP connector > Agency Analytics is a marketing reporting platform that enables digital agencies to monitor SEO, PPC, social media, and other channel performance in... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'agencyanalyticsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Agency Analytics MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'agencyanalyticsmcp_read_client_ad_manager', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "agencyanalyticsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Agency Analytics MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="agencyanalyticsmcp_read_client_ad_manager", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read client site audit, client reputation, client forms** — Fetch a client’s technical site-audit data for a specific connected provider * **Search web, users, clients** — Search the live web and return a compact keyword-research result set: organic results (position, title, link, domain, snippet), related searches, People Also Ask questions, and the answer box when present * **Fetch web** — Fetch a single public web page or document by URL and return its readable text * **Create mcp feedback** — Record user feedback explicitly directed at the AgencyAnalytics MCP server experience — its tools, ergonomics, or quality of results * **Clients browse** — Browse or enumerate clients * **Reports browse client** — List all reports for a client/campaign ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Agentmail MCP connector > Connect to Agentmail MCP. Manage inboxes, send and receive email, handle drafts, threads, and attachments from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'agentmailmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Agentmail MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'agentmailmcp_list_inboxes', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "agentmailmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Agentmail MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="agentmailmcp_list_inboxes", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update thread, inbox, message** — Update a thread’s labels (add or remove) * **Organization select** — Choose which organization your AgentMail operations target (for users who belong to multiple orgs) * **Search threads, messages** — Search threads in an inbox with a full-text query, ranked by relevance * **List organizations, messages, threads** — List the organizations you belong to and show which one is currently selected for AgentMail operations * **Delete thread, inbox, draft** — Delete a thread from an inbox * **Verify agent** — Verify an unverified agent organization using the 6-digit code emailed to the human who signed up, lifting the unverified plan’s caps (1 inbox, 10 sends/day) at no cost ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Ahrefs MCP connector > Connect to Ahrefs MCP to access SEO data including backlinks, keyword research, site audits, rank tracking, and web analytics directly from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'ahrefsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Ahrefs MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'ahrefsmcp_management_brand_radar_reports', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "ahrefsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Ahrefs MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="ahrefsmcp_management_brand_radar_reports", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Analyze backlinks** — retrieve backlink profiles, referring domains, anchors, and broken links for any URL or domain * **Research keywords** — get keyword ideas, search volume, difficulty scores, SERP overviews, and ranking history * **Explore site data** — fetch organic and paid traffic estimates, top pages, and outlinks for any domain * **Track rankings** — monitor keyword positions across countries and devices over time * **Audit sites** — run crawls to surface broken pages, redirect chains, and on-page SEO issues * **Analyze web analytics** — retrieve traffic stats, top pages, UTM breakdowns, and traffic sources for Web Analytics projects ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Airbyte MCP connector > Connect to Airbyte's MCP server to manage data pipelines, sources, destinations, and connections for your data integration workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'airbytemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Airbyte MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'airbytemcp_check_enrollment_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "airbytemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Airbyte MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="airbytemcp_check_enrollment_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Execute skill function** — Invoke one source-controlled function declared by a library skill * **Workspace use** — Switch the active workspace for the session * **Organization use** — Switch the active organization for the session * **Flow start credential** — Start a browser-based credential flow to connect a data source * **Search skills** — Search available skill documentation entries by a basic keyword * **Read skill docs** — Read usage documentation for a skill ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Airops MCP connector > Connect to AirOps MCP. Manage brand kits, run AI-powered analytics, track AEO citations, and automate content workflows from your AI agents. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Airops MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'airopsmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'airopsmcp_list_aeo_page_content_updates', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "airopsmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="airopsmcp_list_aeo_page_content_updates", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update topic, aeo tag, aeo prompt assignments** — Update an existing AEO topic’s name and/or color on a Brand Kit * **Opportunity reject, accept** — Reject pending opportunities for a campaign * **Read grid cell, grid** — Read the full value of a single grid cell * **Case manage brand kit visual use** — Create or update a Visual Use Case for a Brand Kit * **List opportunities, campaigns, answers** — List opportunities for a campaign * **Manage knowledge base** — Create or update a Knowledge Base ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Airparser MCP connector > AI-powered document parser that extracts structured data from PDFs, emails, and other documents. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'airparsermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Airparser MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'airparsermcp_get_extraction_schema_format_guide', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "airparsermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Airparser MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="airparsermcp_get_extraction_schema_format_guide", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sync upload document** — Upload one document to an Airparser inbox and wait for the parsed result * **Update fields meta, extraction schema from json schema, extraction schema** — Enable or disable per-document output metadata fields for an Airparser inbox * **Code test postprocessing, save postprocessing** — Run Airparser post-processing Python code against an existing parsed document without saving it * **Enabled set postprocessing** — Enable or disable the saved Airparser post-processing step for an inbox * **List inboxes, documents** — List active Airparser inboxes available to the authenticated user * **Get postprocessing runtime rules, postprocessing, inbox** — Get the runtime constraints and allowed imports for Airparser post-processing Python code ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Airtable connector > Connect to Airtable. Manage databases, tables, records, and collaborate on structured data 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Airtable credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'airtable' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Airtable:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'airtable_get_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "airtable" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Airtable:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="airtable_get_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Attachment upload** — Upload a file directly to an attachment field on an Airtable record, by sending its base64-encoded content in the request body * **Get view, current user, record** — Retrieve metadata for a single view in an Airtable table, including its name, type (grid, form, calendar, kanban, gallery, etc), and visible field order * **Delete view, base, webhook** — Permanently delete a view from an Airtable table * **Update table, records, field** — Update a table’s name or description in an Airtable base * **Webhook refresh** — Refresh an Airtable webhook to extend its expiration time * **List webhooks, webhook payloads, records** — List all webhooks configured for an Airtable base ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Airtable MCP connector > Connect to Airtable MCP. Manage bases, tables, records, views, fields, and automations from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'airtablemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Airtable MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'airtablemcp_get_create_automation_instructions', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "airtablemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Airtable MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="airtablemcp_get_create_automation_instructions", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update automation, table, records for table** — Replaces the entire draft configuration (trigger, graph, name, description) of an existing automation * **Trigger test automation webhook** — Re-runs the trigger test for a genericWebhookReceived automation and waits briefly for a newly captured payload schema * **Form submit** — Submits a form, creating a new record in the form’s source table * **Search candidate linked records, records, bases** — Searches for records that are valid candidates for a linked-record (foreign-key) field, returning each candidate’s record ID along with the fields the linked-record field is configured to display (the same fields shown on the in-product card) * **Action revert** — Reverts a previous eligible Airtable mutation by performing the inverse write, using the actionId it returned * **List views for table, external accounts, automations** — Lists the views in a table, returning each view’s ID, name, and type ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Akta Pro connector > Connect to Akta Pro to search and monitor company news signals, including sentiment, entities, and industry classification, for sales and market... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'aktapro' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'aktapro_search_news', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "aktapro" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="aktapro_search_news", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search news** — Search company news signals with filters for company, industry, sentiment, entities, and date range ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Akta Pro MCP connector > Connect to Akta Pro MCP to search company news signals, check account status, and access sales intelligence tools directly from your AI agents. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'aktapromcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'aktapromcp_account_status', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "aktapromcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="aktapromcp_account_status", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Traffic website** — Website traffic: engagement metrics, monthly visit estimates, and traffic by acquisition channel * **Posts social, job** — Company social media posts: content type, text, publish date, paid/repost flags, an AI classification, and engagement metrics * **Reviews product, employee** — Product catalog and per-product reviews (G2 et al.) * **Types news** — List the news-type taxonomy (tag codes) for filtering news\_signals * **Signals news** — Fetch a list of news signals by company, industry, topic, or title (JSON) * **Detail news** — Fetch the full article body for specific news id(s) from news\_signals ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # AlphaXiv MCP connector > Connect to AlphaXiv MCP to search and retrieve arXiv research papers, abstracts, authors, and citations from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'alphaxivmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize AlphaXiv MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'alphaxivmcp_find_researchers', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "alphaxivmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize AlphaXiv MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="alphaxivmcp_find_researchers", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Researcher unfollow, follow** — Stop following a researcher * **Folder save papers to, rename, remove papers from** — Add one or more papers (by arXiv id or alphaXiv/arXiv URL) to a folder in the user’s library * **Researchers resolve, find** — Turns a list of people extracted from a webpage or other external source into current, citeable alphaXiv researcher entries * **Folders move papers between** — Move papers from a source folder to a destination folder in a single atomic operation: each paper is added to the destination and removed from the source * **List library, followed researchers** — List the user’s alphaXiv library: their folders (bookmark collections) with folder\_id, name, type, parent\_id, sharing\_status, and paper\_count * **Get researcher papers, researcher, paper content** — Papers on alphaXiv for one or many researchers, grouped per researcher ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Amplemarket connector > Connect to Amplemarket, an AI-powered sales engagement platform, to search and enrich B2B leads, manage email/LinkedIn outreach sequences, and score... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'amplemarket' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'amplemarket_account_info_get', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "amplemarket" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="amplemarket_account_info_get", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List users, tasks types, tasks statuses** — List users in the authenticated Amplemarket workspace, with optional filtering by status, role, or email, and cursor-based pagination * **Skip task** — Skip an Amplemarket task by its ID * **Complete task** — Mark an Amplemarket task as complete by its ID * **Leads sequence add** — Add one or more leads to an existing outreach sequence identified by its ID * **Review phone number** — Submit a data-quality review for a phone number in Amplemarket, flagging it as incorrect (e.g * **Find person, company** — Synchronously find and enrich a single person in the Amplemarket database by email, LinkedIn URL, or name plus company ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Amplitude Analytics connector > Connect to Amplitude's analytics REST APIs: event segmentation, funnels, cohorts, taxonomy, chart annotations, session replay, export, releases, streaming... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Amplitude Analytics credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search users** — Look up a user in Amplitude by Amplitude ID, Device ID, User ID, or a User ID prefix, via the Dashboard REST API’s User Search endpoint * **List lookup tables, user properties, user deletion jobs** — List all lookup tables configured in the project, via the current Lookup Table API 2 (/api/3/lookup\_table) * **Get lookup table, user composition, user activity** — Retrieve a single lookup table’s metadata by name, via the current Lookup Table API 2 (/api/3/lookup\_table/{name}) * **Delete lookup table, user property, event type** — Delete a lookup table via the current Lookup Table API 2 (/api/3/lookup\_table/{name}) * **Cohort upload** — Create a new Amplitude behavioral cohort from an explicit list of user or Amplitude IDs, or update an existing cohort’s membership list wholesale by passing existing\_cohort\_id * **Update user property, group property, event type** — Partially update an existing user property in Amplitude’s taxonomy ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Amplitude Experiment Management connector > Manage Amplitude Experiment feature flags, experiments, mutex groups, holdouts, and deployments. Separate connector from Experiment Evaluation (real-time... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Amplitude Experiment Management credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'amplitudeexperimentmanagement' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'amplitudeexperimentmanagement_list_all_versions', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "amplitudeexperimentmanagement" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="amplitudeexperimentmanagement_list_all_versions", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update mutex group slot, mutex group, holdout group** — Edit which experiments, holdouts, and/or individuals occupy one slot in a mutex group, without touching the slot’s percentage or any other slot * **User remove flag variant, remove experiment variant** — Remove one specific user from a flag variant’s individual-inclusion list, identified by the user’s zero-indexed position in that list — not by user ID * **Users remove all flag variant, remove all experiment variant, add flag variant** — Remove ALL users from a flag variant’s individual-inclusion list in a single call * **List mutex groups, holdout groups, flags** — List all mutex groups in the project * **Get mutex group, holdout group, flag version** — Retrieve a single mutex group’s full configuration by ID — expected to include its slots and which experiments, holdouts, or individuals occupy each one, mirroring the shape accepted by Create Mutex Group (name, description, evaluationMode, bucketingKey, bucketingSalt, and a slots array of {percentage, experiments, holdouts, individuals}) * **Delete flag variant, flag deployment, experiment variant** — Permanently remove a variant from an Amplitude Experiment feature flag ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Anakin MCP connector > Anakin is an AI platform and marketplace that lets you build, deploy, and access a wide range of AI tools and automated workflows. This MCP connector... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'anakinmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Anakin MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'anakinmcp_monitor_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "anakinmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Anakin MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="anakinmcp_monitor_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Action wire write** — Run a Wire WRITE action — one whose type is “write” (it performs a state-changing interaction on the target site): submit a form, add an item to a cart, post or send content, update account settings * **Login wire** — Sign in to a credentials-mode site and get a credential\_id usable immediately with wire\_read\_action / wire\_write\_action * **Build wire** — Request a brand-new Wire action for a website that isn’t in the catalog yet * **List session, monitor** — List your saved browser sessions — encrypted login states captured via the Anakin dashboard or Browser API * **Delete session** — Permanently delete a saved browser session and its encrypted login data * **Create monitor** — Create a scheduled website monitor that checks a URL every intervalMinutes (min 15) and records a change when the content differs — optionally alerting a webhook or email ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Anchor Browser MCP connector > Connect to Anchor Browser MCP to run cloud browser automation, control live browser sessions, extract web data, and let AI agents browse and act on the... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'anchorbrowsermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Anchor Browser MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'anchorbrowsermcp_anchor_tab_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "anchorbrowsermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Anchor Browser MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="anchorbrowsermcp_anchor_tab_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **For anchor wait** — Pause the automation until a specified text appears on the page, a specified text disappears from the page, or a given number of seconds elapses * **Type anchor** — Type text into an editable element in the cloud browser page * **Screenshot anchor take** — Take a screenshot of the current browser page or a specific element * **Select anchor tab** — Switch the active browser tab to the tab at the given zero-based index * **New anchor tab** — Open a new browser tab in the cloud session, optionally navigating it to a specified URL * **List anchor tab** — List all currently open tabs in the cloud browser session, returning their indices and titles or URLs ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Apify MCP connector > Connect to Apify MCP to run web scraping, browser automation, and data extraction Actors directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Apify MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'apifymcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'apifymcp_search_actors', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "apifymcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="apifymcp_search_actors", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Problem report** — Report a problem with Apify’s MCP tools or Actors to the Apify team * **Get key value store record, dataset items, actor run** — Retrieve a record (JSON, text, or binary) from a key-value store by its key * **Run abort actor** — Abort an Actor run that is currently starting or running * **Fetch actor details, apify docs** — Get detailed information about an Actor by its ID or full name (format: ‘username/name’, e.g * **Search actors, apify docs** — Search the Apify Store to FIND and DISCOVER what scraping tools/Actors exist for specific platforms or use cases * **Actor call** — Call any Actor from the Apify Store ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Apollo connector > Connect to Apollo.io to search and enrich B2B contacts and accounts, manage CRM contacts, and automate outreach sequences. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Apollo credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'apollo' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Apollo:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'apollo_get_api_usage', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "apollo" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Apollo:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="apollo_get_api_usage", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update custom field, task, sequence contact status** — Update an existing custom field on contacts, accounts, or deals (opportunities) in your Apollo account * **Get webhook result, email content, credit usage** — Retrieve the result of an asynchronous People Enrichment or Bulk People Enrichment request by its request\_id, without waiting for Apollo’s webhook callback * **Task skip, complete** — Mark an existing task in your team’s Apollo account as skipped, without completing it, by task ID * **Send email** — Immediately send an existing Apollo email message that is in a drafted, scheduled, or failed state * **Search tasks, people, news articles** — Find tasks that your team has created in Apollo, with sorting and pagination * **List remove records from, users, lists** — Remove contacts or accounts from one or more Apollo lists, referencing the lists by name ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Apollo (API Key) connector > Connect to Apollo.io using a master API key to search and enrich B2B contacts and accounts, manage CRM records, sequences, tasks, and deals, and access... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'apolloapikey' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'apolloapikey_get_api_usage', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "apolloapikey" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="apolloapikey_get_api_usage", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update custom field, task, sequence contact status** — Update an existing custom field on contacts, accounts, or deals (opportunities) in your Apollo account * **Get webhook result, email content, credit usage** — Retrieve the result of an asynchronous People Enrichment or Bulk People Enrichment request by its request\_id, without waiting for Apollo’s webhook callback * **Task skip, complete** — Mark an existing task in your team’s Apollo account as skipped, without completing it, by task ID * **Send email, check email** — Immediately send an existing Apollo email message that is in a drafted, scheduled, or failed state * **Search tasks, people, news articles** — Find tasks that your team has created in Apollo, with sorting and pagination * **List remove records from, users, sequences** — Remove contacts or accounts from one or more Apollo lists, referencing the lists by name ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Apollo MCP connector > Connect to Apollo MCP to search B2B contacts, enrich people and organizations, manage CRM records, and enroll prospects in sequences. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'apollomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Apollo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'apollomcp_apollo_contacts_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "apollomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Apollo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="apollomcp_apollo_contacts_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Aggregates apollo website visitors domain** — Return visit counts, unique-visitor counts, and top visited paths for a single visiting company on one of your team’s tracked websites, over a date range * **Update apollo website visitor domain tracker, apollo labels, apollo context center** — Add, edit, or delete a domain in the team’s website visitor domain tracker * **Send apollo website visitor domain tracker, apollo emailer messages, apollo emailer messages email** — Email the Apollo website visitor tracking JavaScript snippet to one or more recipients — typically a developer who will install it on the team’s website * **Script apollo website visitor domain tracker install** — Return the ready-to-embed Apollo website visitor tracking snippet for the team, with the team’s tracker id already substituted in as appId — never hand-assemble the template or guess the loader URL yourself * **Index apollo website visitor domain tracker, apollo labels, apollo fields** — Retrieve the website visitor domain tracker configuration for the team: the tracker id, team id, the list of active allowed referrer domains (with tracking status, contact-level tracking settings, and intent paths), the maximum domain limit for the team, and whether visitor credits are exhausted * **Show apollo webhook result, apollo context center, apollo tasks** — Poll for the result of an asynchronous Apollo enrichment request: either a phone-number reveal started by apollo\_people\_match or apollo\_people\_bulk\_match with reveal\_phone\_number=true, or a waterfall enrichment (email and/or phone) started with run\_waterfall\_email=true and/or run\_waterfall\_phone=true ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # AppSignal MCP connector > AppSignal is an application monitoring and performance management platform providing error tracking, performance monitoring, and alerting for Ruby... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'appsignalmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize AppSignal MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'appsignalmcp_get_applications', 25 toolInput: { context: 'YOUR_CONTEXT' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "appsignalmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize AppSignal MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"context":"YOUR_CONTEXT"}, 27 tool_name="appsignalmcp_get_applications", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update incidents, dashboard visual** — Bulk update AppSignal incidents: change state, severity, assign or unassign team members * **Actions reorder log line** — Reorder log line actions to change their execution order during log ingestion * **Trigger manage, archive** — Create or update an anomaly detection trigger to monitor a metric threshold * **Action manage log line** — Create or update a log line action (trigger, filter, or metrics type) * **Note manage incident** — Create or update a note on an AppSignal incident * **Dashboard manage** — Create or update an AppSignal dashboard (title and description only) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Asana connector > Connect to Asana. Manage tasks, projects, teams, and workflow automation 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Asana credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'asana' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Asana:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'asana_allocations_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "asana" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Asana:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="asana_allocations_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update workspace, user, time tracking category** — Update the name of a workspace or organization * **List workspace events, time tracking category entries, time periods** — Get all events that have occurred across a workspace domain since a sync token was created * **Delete time tracking category, task template, rate** — Permanently delete a time tracking category * **Create time tracking category, rate, organization export** — Create a new time tracking category in a workspace (e.g * **Get time period, rate, organization export** — Get a single time period (e.g * **Run rule trigger** — Trigger an Asana Rule programmatically for a task, passing action data the rule’s action can use ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Asana MCP connector > Connect to Asana MCP server to manage tasks, projects, and teams directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Asana MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'asanamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Asana MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'asanamcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "asanamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Asana MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="asanamcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search objects internal, tasks preview, tasks** — DEPRECATED; DO NOT USE * **Confirm save task changes, save project changes** — DEPRECATED; DO NOT USE * **Event log widget** — DEPRECATED; DO NOT USE * **Get task stories, project internal, workspace agents** — Get the full activity feed (stories) for a task by ID * **Create task preview v4, task confirm, project preview v3** — Generates a visual preview of a single task and asks for confirmation before creation * **Update tasks** — Update one or more tasks in a single operation ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Atlassian Rovo MCP connector > Connect to Atlassian Rovo MCP server to manage Jira issues, Confluence pages, and Compass components directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Atlassian Rovo MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'atlassianmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Atlassian Rovo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'atlassianmcp_fetch', 25 toolInput: { id: 'https://example.com/id' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "atlassianmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Atlassian Rovo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"https://example.com/id"}, 27 tool_name="atlassianmcp_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Manage Jira issues** — create, edit, transition, comment on, and link issues; add worklogs * **Search with JQL** — query issues using Jira Query Language with full field and filter support * **Work with Confluence** — create, update, and retrieve pages; add footer and inline comments * **Manage Compass components** — create, get, and search services, libraries, and applications; define custom fields and relationships * **Look up users and resources** — resolve Atlassian account IDs, list accessible cloud sites, and find project metadata * **Fetch Atlassian content** — retrieve any Atlassian object by its ARI or URL (e.g. a Jira issue or Confluence page URL) ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Get your cloud ID Most Atlassian Rovo MCP tools require a `cloudId` — the UUID that identifies your Atlassian cloud site. Call `atlassianmcp_getaccessibleatlassianresources` once to retrieve it, then pass the `id` field value in every subsequent tool call. * Node.js ```typescript 1 // Step 1 — get the cloud ID 2 const resources = await actions.executeTool({ 3 connectionName: 'atlassianmcp', 4 identifier: 'user_123', 5 toolName: 'atlassianmcp_getaccessibleatlassianresources', 6 toolInput: {}, 7 }); 8 const cloudId = resources[0].id; 9 10 // Step 2 — use cloudId in subsequent calls 11 const issue = await actions.executeTool({ 12 connectionName: 'atlassianmcp', 13 identifier: 'user_123', 14 toolName: 'atlassianmcp_getjiraissue', 15 toolInput: { 16 cloudId, 17 issueIdOrKey: 'KAN-1', 18 }, 19 }); 20 console.log(issue); ``` * Python ```python 1 # Step 1 — get the cloud ID 2 resources = actions.execute_tool( 3 connection_name="atlassianmcp", 4 identifier="user_123", 5 tool_name="atlassianmcp_getaccessibleatlassianresources", 6 tool_input={}, 7 ) 8 cloud_id = resources[0]["id"] 9 10 # Step 2 — use cloud_id in subsequent calls 11 issue = actions.execute_tool( 12 connection_name="atlassianmcp", 13 identifier="user_123", 14 tool_name="atlassianmcp_getjiraissue", 15 tool_input={ 16 "cloudId": cloud_id, 17 "issueIdOrKey": "KAN-1", 18 }, 19 ) 20 print(issue) ``` The `atlassianmcp_getaccessibleatlassianresources` response looks like this: ```json 1 [ 2 { 3 "id": "a4c9b3e2-1234-5678-abcd-ef0123456789", 4 "name": "My Company", 5 "url": "https://mycompany.atlassian.net", 6 "scopes": ["read:jira-work", "write:jira-work", "read:confluence-content.all"] 7 } 8 ] ``` Use `id` as the `cloudId` parameter. If the user belongs to multiple Atlassian sites, the list contains one entry per site — pick the one matching the target `url`. ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Attention connector > Connect to Attention for AI insights, conversations, teams, and workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'attention' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'attention_connection_report_get', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "attention" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="attention_connection_report_get", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List users, teams, team members** — List users in the Attention organization, with optional filters by ID, email, or team * **Update user, team, conversation** — Update an existing Attention user’s name, password, role, seat type, or team assignments * **Delete user** — Permanently remove a user from the Attention organization, revoking their access * **Create user, team, snippet** — Create a new user in the Attention organization with an email, role, seat type, and one or more team assignments * **Get usage report, team, scorecards summary** — Get API/feature usage statistics (coaching sessions, calls viewed, comments left, snippets created, AI queries, etc.) for specified users or teams over a date range * **Import conversation** — Import an externally recorded conversation into Attention by supplying a media URL and the owning user ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Attio connector > Connect to Attio CRM to manage contacts, companies, deals, notes, tasks, and lists with a modern relationship management platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Attio credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'attio' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Attio:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'attio_get_current_token_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "attio" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Attio:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="attio_get_current_token_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List overwrite, views for object, views for list** — Update attribute values on a list entry in Attio, overwriting (replacing/removing) any existing multiselect values * **Records merge** — Merges two records of the same object together * **File download** — Downloads a file by redirecting to a signed URL * **Delete call recording, list entry, file** — Deletes the specified call recording * **Create meeting, folder, call recording** — Creates a new meeting in Attio * **Values append record** — Update a record’s attributes in Attio, appending to multiselect attributes instead of replacing them ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Attio MCP connector > Connect to Attio MCP. Access and manage CRM records, lists, notes, tasks, emails, and workspace data across people, companies, and deals. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'attiomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Attio MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'attiomcp_list_comments', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "attiomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Attio MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="attiomcp_list_comments", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Records merge** — Merge two records of the same object into one * **Whoami records** — Returns information about the current user’s identity and workspace membership, including their email, name, workspace member ID, access level, and workspace name * **Record upsert** — Create or update a people, companies, or other record using a matching attribute to find an existing record * **Update task, record, note** — Update an existing task’s deadline, completion status, assignee, or linked record * **Search semantic** — Search all notes in the workspace using semantic similarity to find notes where specific topics were discussed, even if exact keywords are not present * **Run basic report** — Run an aggregate report on records in an object or entries in a list, computing totals, averages, minimums, maximums, or grouped breakdowns ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Axiom MCP connector > Axiom is a cloud-native data analytics and observability platform for ingesting, storing, and querying logs, events, traces, and metrics at scale. The MCP... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'axiommcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Axiom MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'axiommcp_check_monitors', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "axiommcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Axiom MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="axiommcp_check_monitors", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Send feedback** — Share feedback about the Axiom MCP server experience, such as a misleading tool description, a confusing result or error message, a missing capability, or praise for something that worked well * **Update notifier, monitor, dashboard chart** — Update an existing notifier by ID using a full notifier JSON payload * **Search metrics** — Search tag values across all metrics in a dataset (kind otel-metrics-v1) for a specific entity name (a service, host, or region) and return the metric names associated with it, along with type, temporality, and unit metadata * **Query metrics, dataset** — Query OTel metrics from Axiom using MPL (Metrics Processing Language), not APL, over a given time range (defaults to the last 30 minutes) * **List notifiers, metrics, metric tags** — List all notifiers (notification channels such as email, Slack, PagerDuty) configured in the workspace * **Get saved queries, monitor history, metric tag values** — List all saved APL queries in the Axiom workspace ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Betterstack MCP connector > Monitor uptime, manage logs, and respond to incidents with Better Stack's observability platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'betterstackmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Betterstack MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'betterstackmcp_status_pages', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "betterstackmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Betterstack MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="betterstackmcp_status_pages", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update status page section, status page resource, status page** — Rename a status page section or move it by setting its position * **Roles team** — List the roles defined in a Better Stack organization, including their role\_id and system-role identifier (admin, billing\_admin, team\_lead, responder, member, or “custom”) * **Members team** — List the members of a Better Stack team, including pending invitations * **Sections status page** — List the sections (resource groups) of a status page * **Variable set dashboard, remove dashboard** — Create or update a dashboard template variable — a user-facing filter in the dashboard toolbar, referenced in chart SQL as {{name}} (required — the chart errors until it resolves to a value) or \[\[ AND col = {{name}} ]] (optional — the whole \[\[ . * **Member remove team, invite team** — Remove a member from a Better Stack team, or cancel a pending invitation ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google BigQuery connector > BigQuery is Google Cloud’s fully-managed enterprise data warehouse for analytics at scale. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google BigQuery credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'bigquery' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google BigQuery:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'bigquery_list_projects', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "bigquery" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google BigQuery:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="bigquery_list_projects", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update table, row access policy, routine** — Update metadata for an existing BigQuery table, such as its schema (e.g * **Dataset undelete, replace, insert** — Restore a recently deleted BigQuery dataset * **Permissions test table iam, test row access policy iam, test routine iam** — Check which of a given set of IAM permissions the caller has on a BigQuery table or view * **Policy set table iam, set routine iam, insert row access** — Set the IAM access control policy on a BigQuery table or view, replacing any existing policy bindings * **Run query** — Execute a SQL query synchronously against BigQuery and return results immediately * **Table replace, insert** — Full replace of a table’s mutable metadata (PUT semantics) — any field you omit will be reset to its default, unlike bigquery\_update\_table which only changes fields you provide ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # BigQuery (Service Account) connector > Connect to Google BigQuery using a GCP service account for server-to-server authentication without user login. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your BigQuery (Service Account) credentials with Scalekit so it handles the token lifecycle. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Permissions test table iam, test row access policy iam, test routine iam** — Check which of a given set of IAM permissions the caller has on a BigQuery table or view * **List row access policies, projects, tables** — List the row access policies defined on a BigQuery table * **Get table iam policy, service account, row access policy iam policy** — Retrieve the IAM access control policy currently set on a BigQuery table or view * **Query insert** — Submit an asynchronous BigQuery query job * **Job cancel** — Request cancellation of a running BigQuery job * **Run dry, query** — Validate a SQL query and estimate its cost without executing it ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Biomni MCP connector > Connect to Biomni MCP by phylo.bio, an AI biomedical research assistant. Analyze life-sciences data, interpret genomic variants, query curated databases... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'biomnimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Biomni MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'biomnimcp_list_projects', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "biomnimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Biomni MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="biomnimcp_list_projects", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Review request** — Run a Scientific Review of a completed task — same as the “Review” button in the Biomni web app * **List files, workspaces, tasks** — List the input files already uploaded to a project * **Update wait for next** — Long-poll for the next batch of progress on the agent’s current reply, returning only newly-added content blocks since the last call * **File upload** — Upload a small text file (VCF, CSV, TSV, JSON, or code) to a project’s drive by passing its content inline as a UTF-8 string * **Workspace switch** — Switch the caller’s active workspace so that subsequent calls (list\_projects, create\_project, task operations) act in the new workspace * **Task start new** — Auto-create a Biomni task in a project and send the first message in a single call, triggering AI agent execution ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Bio Render MCP connector > Connect to BioRender MCP. Search BioRender's scientific icon and figure template libraries to build publication-ready biological illustrations. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'biorendermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Bio Render MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'biorendermcp_search-icons', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "biorendermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Bio Render MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="biorendermcp_search-icons", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search-templates records** — Search BioRender’s scientific figure template library * **Search-icons records** — Search BioRender’s scientific icon library by keyword ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Bitbucket connector > Connect to Bitbucket. Manage repositories, pipelines, pull requests, and code collaboration. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Bitbucket credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'bitbucket' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Bitbucket:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'bitbucket_user_emails_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "bitbucket" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Bitbucket:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="bitbucket_user_emails_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List workspace webhooks, snippets, repository forks** — Returns a paginated list of webhooks installed on a Bitbucket workspace * **Update workspace webhook, pull request task, deployment variable** — Updates an existing webhook on a Bitbucket workspace, including its URL, events, and active status * **Get workspace webhook, snippet, pull request patch** — Returns the details of a specific webhook installed on a Bitbucket workspace * **Delete workspace webhook, snippet, report** — Deletes a webhook from a Bitbucket workspace * **Create workspace webhook, snippet, report** — Creates a new webhook on a Bitbucket workspace * **Upload issue attachment, download** — Upload a new attachment to a Bitbucket issue ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Bitly MCP connector > Connect with Bitly MCP for URL shortening, link analytics, and branded links. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'bitlymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Bitly MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'bitlymcp_get_custom_domains', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "bitlymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Bitly MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="bitlymcp_get_custom_domains", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create and manage short links** — shorten URLs, create links with custom back-halves, update link metadata, and delete links * **Create and manage QR codes** — generate QR codes for links, update QR code settings, and retrieve QR code images * **Analyze link performance** — get click summaries, engagement metrics, and breakdowns by city, country, device, referrer, and referring domain * **Analyze QR code scans** — get scan summaries and breakdowns by city, country, device, and browser * **Analyze group-level engagement** — query top links, clicks, scans, and engagement trends across all links in a group * **Manage account structure** — retrieve organizations, groups, custom domains, and user details ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Bitquery MCP connector > Connect to Bitquery MCP. Query on-chain DEX trading data, token prices, OHLCV series, trader profiles, and trending tokens across multiple blockchains... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'bitquerymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Bitquery MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'bitquerymcp_find_currencies', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "bitquerymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Bitquery MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="bitquerymcp_find_currencies", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Trades tx, pool recent** — DECODED DEX swaps inside ONE transaction — every swap leg of a tx: side, tokens, base/quote amounts, USD size, price, DEX and pool * **Transfers tron tx, solana tx, optimism tx** — All transfers inside ONE OR SEVERAL Tron (trx, TRX, TRON) transactions (sender → receiver, currency, amount) — pass one tx hash or several separated by ”|” * **Sql tron transfers raw, solana transfers raw, optimism transfers raw** — LAST RESORT — arbitrary READ-ONLY SQL against the Tron transfers database * **Out tron transfers, solana transfers, optimism transfers** — OUTGOING Tron (trx, TRX, TRON) transfers from an address — where this wallet sent funds * **In tron transfers, solana transfers, optimism transfers** — INCOMING Tron (trx, TRX, TRON) transfers to an address — where this wallet received funds from * **Hop tron trace next, solana trace next, optimism trace next** — CONVERGENCE primitive for Tron (trx, TRX, TRON) tracing: aggregate an address’s OUTGOING flow by counterparty (Σ amount, count, first/last seen), largest first ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Bonsai MCP connector > Connect to Bonsai, the all-in-one business management platform for freelancers and agencies. Manage projects, tasks, CRM contacts, deals, invoices, and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'bonsaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Bonsai MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'bonsaimcp_list_board_groups', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "bonsaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Bonsai MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="bonsaimcp_list_board_groups", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update time entry, task, invoice item** — Update an existing time entry in the user’s current company * **List time entries, task statuses, subtasks** — List time entries in the user’s current company, paginated, newest first * **Get note, task** — Fetch a single note by its id, including what it says as `content_plain_text` — the field a list response always leaves out, so read a note here whenever you need its body * **Task destroy** — Soft-delete a task in Bonsai by its UUID * **Note destroy** — Delete a note by its id * **Item destroy invoice** — Remove a single line item from an invoice; any linked time entries are unbilled and the invoice total is recomputed ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Box connector > Box is a cloud content management platform. Manage files, folders, users, groups, collaborations, tasks, comments, webhooks, search, and more using the... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Box credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'box' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Box:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'box_collections_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "box" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Box:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="box_collections_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get upload session, sign request, retention policy** — Retrieve the status and configuration of a chunked upload session, including its part size, total parts expected, and number of parts processed so far * **Create upload session, sign request, retention policy** — Create a chunked upload session for uploading a new large file (over 50MB) to a Box folder * **Abort upload session** — Abort and remove a chunked upload session, discarding any parts already uploaded * **List sign requests, retention policy assignments, retention policies** — Lists Box Sign requests in the enterprise * **Cancel sign request** — Cancels an in-progress Box Sign request so it can no longer be signed * **Update retention policy, webhook, web link** — Update an existing retention policy’s name, description, disposition action, modifiability, notification settings, or status ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Box MCP connector > Connect to Box via MCP to manage files, folders, collaborations, users, groups, tasks, comments, and search content directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Box MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'boxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Box MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'boxmcp_list_hubs', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "boxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Box MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="boxmcp_list_hubs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **I who am** — Returns detailed information about the currently authenticated Box user, including user profile data, identification, contact information, role details, and account settings * **Version upload file** — Uploads a new version of an existing Box file by replacing its content with the provided text * **File upload, move, copy** — Uploads a new text file to Box * **Update metadata template, hub, folder properties** — Updates a metadata template schema (add, edit, remove, or reorder fields, enum options, or multiSelect options; or rename the template) * **Metadata set folder, set file** — Creates or updates a metadata template instance on a Box folder (applies the template the first time, or updates it if already applied) * **Search folders by name, files metadata, files keyword** — Searches for folders by name within Box using keyword matching ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Brandfetch MCP connector > Connect to Brandfetch's MCP server to search, retrieve, and enrich brand data — logos, colors, fonts, and company details — directly from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'brandfetchmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Brandfetch MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'brandfetchmcp_brand_search', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "brandfetchmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Brandfetch MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="brandfetchmcp_brand_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Send feedback** — Send feedback about the Brandfetch MCP server to the Brandfetch team * **Get brand context, brand, asset base64** — Get LLM-ready brand context for a known domain — voice, audience, positioning, style * **Transaction enrich** — Identify a merchant brand from a credit card or bank statement string * **Urls build logo** — Construct Brandfetch Logo CDN URLs for one or more brands * **Search brand** — Search for brands by name using Brandfetch’s search index ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Brave Search connector > Connect to Brave Search to perform web, image, video, and news searches with privacy-focused results, plus AI-powered suggestions and spellcheck. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'brave' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'brave_local_place_search', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "brave" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="brave_local_place_search", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get rich results** — Fetch the enriched real-time ‘rich’ result (weather, stocks, sports scores, currency conversion, package tracking, etc.) for a callback\_key * **Descriptions local** — Fetch AI-generated descriptions for locations using IDs from a Brave web search response * **Summary summarizer** — Fetch the complete AI-generated summary for a summarizer key * **Search web, local place, image** — Search the web using Brave Search’s privacy-focused search engine * **Completions chat** — Get AI-generated answers grounded in real-time Brave Search results using an OpenAI-compatible chat completions interface * **Pois local** — Fetch detailed Point of Interest (POI) data for up to 20 location IDs returned by a Brave web search response ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Brevo MCP connector > Connect to Brevo MCP. Manage email and SMS campaigns, transactional emails, contacts, lists, automations, and loyalty programs from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'brevomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Brevo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'brevomcp_accounts_get_corporate_invited_users_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "brevomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Brevo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="brevomcp_accounts_get_corporate_invited_users_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Send whatsapp management, whatsapp campaigns, transac templates** — Send a WhatsApp message to one or more contacts * **Get whatsapp management, whatsapp campaigns** — Retrieve a paginated list of individual WhatsApp event records (unaggregated), including event type, contact number, sender number, message ID, timestamp, and contextual fields like body text, media URL, and error reason where applicable * **Create whatsapp management, whatsapp campaigns, webhooks management** — Create a new WhatsApp message template with the specified name, language, category, and body text * **Update whatsapp campaigns, webhooks management, templates** — Update an existing WhatsApp campaign’s name, status, recipients, or scheduled sending time * **Delete whatsapp campaigns, webhooks management, transac templates** — Delete a WhatsApp campaign by its campaign ID * **History webhooks management export webhooks** — Exports webhook event history to CSV format for analysis and reporting ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Bugsnag MCP connector > Connect to Bugsnag MCP. Monitor errors, releases, traces, and span groups across your projects from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'bugsnagmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Bugsnag MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'bugsnagmcp_bugsnag_get_current_project', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "bugsnagmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Bugsnag MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="bugsnagmcp_bugsnag_get_current_project", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update bugsnag** — Update the status of an error (e.g., ignore, snooze, open, or mark as fixed) * **Groupings bugsnag set network endpoint** — Set network endpoint grouping rules for a project * **List bugsnag** — Retrieve available trace attribute fields for filtering * **Get bugsnag** — Retrieve all spans within a specific distributed trace ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Buildkite MCP connector > Connect to Buildkite MCP. Manage CI/CD pipelines, builds, agents, clusters, and test suites from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'buildkitemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Buildkite MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'buildkitemcp_list_skills', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "buildkitemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Buildkite MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="buildkitemcp_list_skills", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Build wait for, rebuild, cancel** — Wait for a build to reach a terminal state (passed, failed, canceled, skipped, not\_run, or blocked on a block step), polling for up to 45 seconds * **Skill load** — Load the full content of a skill guide by name * **List tests, skills, jobs** — List tests in a Buildkite Test Engine suite with execution metrics aggregated over a selected time window * **Get job, build failure summary, test run** — Get a single job by its UUID * **Organization user token** — Get the organization associated with the user token used for this request * **Update pipeline schedule, pipeline, cluster queue** — Modify an existing pipeline schedule’s cron expression, branch, environment variables, or enabled state ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # BuiltWith MCP connector > BuiltWith tracks the technology stacks of millions of websites. The BuiltWith MCP server lets AI agents look up a site's technology profile, track... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'builtwithmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'builtwithmcp_whoami_api', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "builtwithmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="builtwithmcp_whoami_api", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Api x402 vector, x402 vat, x402 trust** — Vector similarity search across BuiltWith technologies and categories * **Pricing x402** — Show prepaid batch-credit pricing, x402 configuration, and List pass tiers * **List x402, mcp** — Purchase a 30-day Basic ($295, 2 technology and 2 keyword reports) or Pro ($495, 50 and 50) List API pass with Base USDC * **Search x402 keywords, keywords** — Search websites containing a keyword with a valid x402 List pass * **Lookup x402 domain, domain** — Returns live web technologies for one domain using one prepaid credit * **Json x402 domain api, domain api, ask api** — Raw Domain API JSON lookup for one or more comma-separated domains ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Calendly connector > Connect to Calendly. Access user profile, events, and scheduling workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Calendly credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'calendly' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Calendly:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'calendly_contacts_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "calendly" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Calendly:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="calendly_contacts_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List meeting recaps, event type hosts, contacts** — List Notetaker meeting recaps, with optional filters by host user and scheduled event * **Update meeting recap, contact, event type availability schedules** — Update a meeting recap’s title * **Get meeting recap transcript, meeting recap, contact** — Retrieve the transcript for a meeting recap * **Delete meeting recap, contact, webhook subscription** — Delete a meeting recap * **Create event invitee, contact, invitee no show** — Books a Calendly meeting directly via the Scheduling API, without redirects, iframes, or Calendly-hosted UI * **Revoke organization invitation** — Revokes a pending invitation to a Calendly organization ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Calendly MCP connector > Connect to the Calendly MCP server to manage scheduled events, invitees, event types, and availability directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Calendly MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'calendlymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Calendly MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'calendlymcp_list_calendly_skills', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "calendlymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Calendly MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="calendlymcp_list_calendly_skills", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Skill load calendly** — Load a Calendly skill guide that provides domain-specific context, recommended queries, and best practices for working with Calendly tools * **List calendly skills, routing forms** — List or search available Calendly skill guides * **Get users, routing forms** — Use: Fetch profile for a specific user by URI * **Create shares, scheduling links, organizations** — Use: Create a single-use share link for a one-on-one event type with per-link overrides When: User wants a single-use link with any customization (duration, scheduling window, location, or availability) * **Invitation organizations revoke organization** — Use: Revoke a pending organization invitation * **Delete meetings** — Use: Remove a no-show mark from an invitee ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Resolve the connected user first Most Calendly tools need the connected host’s user URI. Call `calendlymcp_users_get_current_user` once at the start of a workflow, then reuse the returned `resource.uri` (and `timezone`) in later calls. * Node.js ```typescript 1 const me = await actions.executeTool({ 2 connectionName: 'calendlymcp', 3 identifier: 'user_123', 4 toolName: 'calendlymcp_users_get_current_user', 5 toolInput: {}, 6 }); 7 const userUri = me.resource.uri; 8 console.log(userUri, me.resource.timezone); ``` * Python ```python 1 me = actions.execute_tool( 2 connection_name="calendlymcp", 3 identifier="user_123", 4 tool_name="calendlymcp_users_get_current_user", 5 tool_input={}, 6 ) 7 user_uri = me["resource"]["uri"] 8 print(user_uri, me["resource"]["timezone"]) ``` ### List upcoming meetings and their invitees Use `calendlymcp_meetings_list_events` to fetch scheduled meetings, then `calendlymcp_meetings_list_event_invitees` to see who is attending a specific meeting. Pass the `user` URI from the previous step and filter by `status` to limit results to active meetings. * Node.js ```typescript 1 // Step 1 — list active meetings for the connected user 2 const events = await actions.executeTool({ 3 connectionName: 'calendlymcp', 4 identifier: 'user_123', 5 toolName: 'calendlymcp_meetings_list_events', 6 toolInput: { 7 user: userUri, 8 status: 'active', 9 count: '20', 10 }, 11 }); 12 const meetingUri = events.collection[0].uri; 13 14 // Step 2 — list the invitees for that meeting 15 const invitees = await actions.executeTool({ 16 connectionName: 'calendlymcp', 17 identifier: 'user_123', 18 toolName: 'calendlymcp_meetings_list_event_invitees', 19 toolInput: { uri: meetingUri }, 20 }); 21 console.log(invitees); ``` * Python ```python 1 # Step 1 — list active meetings for the connected user 2 events = actions.execute_tool( 3 connection_name="calendlymcp", 4 identifier="user_123", 5 tool_name="calendlymcp_meetings_list_events", 6 tool_input={ 7 "user": user_uri, 8 "status": "active", 9 "count": "20", 10 }, 11 ) 12 meeting_uri = events["collection"][0]["uri"] 13 14 # Step 2 — list the invitees for that meeting 15 invitees = actions.execute_tool( 16 connection_name="calendlymcp", 17 identifier="user_123", 18 tool_name="calendlymcp_meetings_list_event_invitees", 19 tool_input={"uri": meeting_uri}, 20 ) 21 print(invitees) ``` ### Book a slot on an event type Find a bookable slot with `calendlymcp_event_types_list_event_type_available_times`, then book it with `calendlymcp_meetings_create_invitee`. Pass the UTC `start_time` from the availability response verbatim — do not rewrite it to a local label. Confirm the slot before booking Always read available times first and pass the returned UTC `start_time` straight into the booking call. Booking without confirming availability can fail or double-book. * Node.js ```typescript 1 // Step 1 — find available times for the event type 2 const slots = await actions.executeTool({ 3 connectionName: 'calendlymcp', 4 identifier: 'user_123', 5 toolName: 'calendlymcp_event_types_list_event_type_available_times', 6 toolInput: { 7 event_type: 'https://api.calendly.com/event_types/EVENT_TYPE_UUID', 8 start_time: '2026-07-01T00:00:00Z', 9 end_time: '2026-07-07T00:00:00Z', 10 }, 11 }); 12 const startTime = slots.collection[0].start_time; 13 14 // Step 2 — book the slot for an invitee 15 const booking = await actions.executeTool({ 16 connectionName: 'calendlymcp', 17 identifier: 'user_123', 18 toolName: 'calendlymcp_meetings_create_invitee', 19 toolInput: { 20 post_invitee_request: { 21 event_type: 'https://api.calendly.com/event_types/EVENT_TYPE_UUID', 22 start_time: startTime, 23 name: 'Jordan Lee', 24 email: 'jordan@example.com', 25 }, 26 }, 27 }); 28 console.log(booking); ``` * Python ```python 1 # Step 1 — find available times for the event type 2 slots = actions.execute_tool( 3 connection_name="calendlymcp", 4 identifier="user_123", 5 tool_name="calendlymcp_event_types_list_event_type_available_times", 6 tool_input={ 7 "event_type": "https://api.calendly.com/event_types/EVENT_TYPE_UUID", 8 "start_time": "2026-07-01T00:00:00Z", 9 "end_time": "2026-07-07T00:00:00Z", 10 }, 11 ) 12 start_time = slots["collection"][0]["start_time"] 13 14 # Step 2 — book the slot for an invitee 15 booking = actions.execute_tool( 16 connection_name="calendlymcp", 17 identifier="user_123", 18 tool_name="calendlymcp_meetings_create_invitee", 19 tool_input={ 20 "post_invitee_request": { 21 "event_type": "https://api.calendly.com/event_types/EVENT_TYPE_UUID", 22 "start_time": start_time, 23 "name": "Jordan Lee", 24 "email": "jordan@example.com", 25 }, 26 }, 27 ) 28 print(booking) ``` ### Share a single-use scheduling link Use `calendlymcp_scheduling_links_create_single_use_scheduling_link` to generate a one-time booking link for an event type, then send the returned `booking_url` to the invitee. Use this when you want the link to follow the event type’s existing settings without overrides. * Node.js ```typescript 1 const link = await actions.executeTool({ 2 connectionName: 'calendlymcp', 3 identifier: 'user_123', 4 toolName: 'calendlymcp_scheduling_links_create_single_use_scheduling_link', 5 toolInput: { 6 create_scheduling_link_request: { 7 owner: 'https://api.calendly.com/event_types/EVENT_TYPE_UUID', 8 owner_type: 'EventType', 9 max_event_count: 1, 10 }, 11 }, 12 }); 13 console.log(link.resource.booking_url); ``` * Python ```python 1 link = actions.execute_tool( 2 connection_name="calendlymcp", 3 identifier="user_123", 4 tool_name="calendlymcp_scheduling_links_create_single_use_scheduling_link", 5 tool_input={ 6 "create_scheduling_link_request": { 7 "owner": "https://api.calendly.com/event_types/EVENT_TYPE_UUID", 8 "owner_type": "EventType", 9 "max_event_count": 1, 10 }, 11 }, 12 ) 13 print(link["resource"]["booking_url"]) ``` ### Cancel a meeting Use `calendlymcp_meetings_cancel_event` with the meeting `uri` from `calendlymcp_meetings_list_events`. Canceling notifies every invitee, so confirm the action with the user first. To reschedule instead, surface the invitee’s `reschedule_url` rather than canceling. * Node.js ```typescript 1 await actions.executeTool({ 2 connectionName: 'calendlymcp', 3 identifier: 'user_123', 4 toolName: 'calendlymcp_meetings_cancel_event', 5 toolInput: { 6 uri: meetingUri, 7 create_scheduled_event_cancellation_request: 'Host unavailable — will follow up to reschedule.', 8 }, 9 }); ``` * Python ```python 1 actions.execute_tool( 2 connection_name="calendlymcp", 3 identifier="user_123", 4 tool_name="calendlymcp_meetings_cancel_event", 5 tool_input={ 6 "uri": meeting_uri, 7 "create_scheduled_event_cancellation_request": "Host unavailable — will follow up to reschedule.", 8 }, 9 ) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Cal MCP connector > Connect to Cal MCP. Manage bookings, event types, schedules, and availability from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'calmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Cal MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'calmcp_get_bookings', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "calmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Cal MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="calmcp_get_bookings", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update schedule, org membership, me** — Update an existing schedule * **Booking reschedule, confirm, cancel** — Reschedule a booking to a new time * **Absent mark booking** — Mark host or attendees as absent for a past booking * **Get schedules, schedule, org routing forms** — List all schedules for the authenticated user * **Delete schedule, org membership, event type** — Delete a schedule by its numeric ID * **Create schedule, org membership, event type** — Create a new schedule ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Candid MCP connector > Connect to Candid MCP. Search nonprofit organizations, explore philanthropic data, and classify social sector activities using Candid's knowledge base. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'candidmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Candid MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'candidmcp_search_organizations', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "candidmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Candid MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="candidmcp_search_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Terms taxonomy** — Classify text using Candid’s Philanthropy Classification System (PCS) taxonomy to get subject and population codes * **Search organizations** — Search Candid’s database for nonprofits and grantmaking organizations by name, mission, location, or type of work * **Resources knowledge** — Search Candid’s knowledge base for articles, blog posts, research reports, and training content about the social and philanthropic sector * **Organizations identify mentioned** — Resolve nonprofit names mentioned in text to Candid profile URLs * **Locations identify** — Detect and resolve geographic names in text to Geonames IDs for use in organization search filters * **Date current** — Get today’s date for use in time-sensitive queries and data requests ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Canva connector > Connect to Canva's Connect API to manage designs, assets, folders, brand templates, comments, autofills, exports, and analytics on the user's behalf via... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Canva credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'canva' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Canva:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'canva_brand_template_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "canva" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Canva:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="canva_brand_template_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get oidc userinfo, design import, asset upload** — Fetch standard OpenID Connect UserInfo claims for the authorized user — the same claims returned in an id\_token during authorization * **Create resize, merge, folder** — Starts a new asynchronous job to create a resized copy of a design * **Update folder, asset** — Update a Canva folder’s details using its folder ID * **List folder items, design pages, design** — List the items inside a Canva folder, including each item’s type (design, folder, image, or brand\_template) * **Move folder item** — Move an item (a folder, design, image asset, or brand template) to another folder in Canva * **Delete folder, asset** — Delete a Canva folder using its folder ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Carbone.io MCP connector > Connect to Carbone.io MCP. Upload templates, render documents by merging templates with JSON data, convert between 100+ formats, and manage template... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Carbone.io MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'carboneiomcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'carboneiomcp_get_api_status', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "carboneiomcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="carboneiomcp_get_api_status", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Template upload, download** — Upload and store a reusable Carbone template * **Update template metadata** — Update the metadata of a stored template: name, comment, category, tags, deployment timestamp, or expiration * **Document render, convert** — Generate a document by merging a Carbone template with JSON data * **List templates, tags, categories** — List stored Carbone templates with filtering, search, and pagination * **Get capabilities, api status** — Returns a summary of all Carbone capabilities: supported formats, features, tool usage examples, and links to full documentation * **Delete template** — Delete a stored Carbone template ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Carta MCP connector > Connect to Carta. Manage equity cap tables, fund administration, company accounts, and ownership data for venture-backed companies. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'cartamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Carta MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'cartamcp_get_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "cartamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Carta MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="cartamcp_get_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Event track ui** — Record a UI event (click, view, or other interaction) from a Carta MCP interface so it shows up in analytics * **Checkpoint skill** — Record a named execution milestone for a running skill (explicit invocation only) * **Search tools** — Search for Carta MCP tools using a natural language query * **Permissions request** — Generate an authorization link to grant Carta MCP access to your account * **Read resource** — Read a Carta MCP resource by its URI * **List resources, contexts, accounts** — List all available Carta MCP resources and resource templates ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Catchr MCP connector > Catchr is a data connector platform that syncs marketing and analytics data from ad platforms (Google Ads, Facebook Ads, etc.) to data warehouses and BI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'catchrmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Catchr MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'catchrmcp_list_all_fields', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "catchrmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Catchr MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="catchrmcp_list_all_fields", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Run api request json, describe** — Execute the Catchr API request in JSON mode for one or multiple accounts * **List sources, platforms, fields for account** — List network authorizations (sources) for the authenticated company, with optional available accounts ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ChiliPiper MCP connector > Connect to ChiliPiper MCP. Schedule meetings, manage routing rules, track distributions, and automate handoffs from your AI agents. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your ChiliPiper MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'chilipipermcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'chilipipermcp_campaign_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "chilipipermcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="chilipipermcp_campaign_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update webhook, web experience, scheduling link** — Toggles a webhook’s enabled state (pause or resume deliveries), matched by its (triggerType, url) identity * **Secret webhook rotate** — Generates a new webhook signing secret for the tenant and returns it * **List webhook, web experience, scheduling link** — Returns all webhooks configured for the tenant * **Get webhook, web experience, meeting type** — Returns the tenant’s webhook signing secret — the single key shared by all of the tenant’s webhooks that signs every delivery * **Delete webhook, web experience, team** — Unsubscribes a webhook, matched by its (triggerType, url) identity; deliveries for that subscription stop immediately * **Create webhook, web experience, team** — Subscribes a url to a meeting lifecycle event (MeetingCreated | MeetingUpdated | MeetingDeleted); each firing delivers a signed POST to that absolute https url ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Chorus connector > Connect to Chorus.ai to sync calls, transcripts, conversation intelligence, and analytics. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search users** — Search Chorus users by free-text query, e.g * **List users, teams, conversations** — List users in the Chorus account, with optional team or role filters * **Get user, team, engagement** — Retrieve a single Chorus user by ID * **Filter engagements** — Search Chorus engagements (calls, meetings, and dialer activity) matching the given type, participant, outcome, and date-range criteria ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Circleback MCP connector > Circleback is an AI meeting notes and conversation intelligence platform. The Circleback MCP server provides a standardized interface that allows any... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'circlebackmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Circleback MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'circlebackmcp_findcompanies', 25 toolInput: { searchTerms: [] }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "circlebackmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Circleback MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"searchTerms":[]}, 27 tool_name="circlebackmcp_findcompanies", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Findcompanies records** — Find companies matching the given search terms * **Searchtranscripts records** — Search meeting transcripts to find transcript chunks that match a given search term * **Searchsupportarticles records** — Search for support articles about Circleback to find relevant documentation and help content * **Searchmeetings records** — Find meetings that match a given search term or filter * **Searchemails records** — Search the user’s connected email accounts for email threads matching a query * **Searchcalendarevents records** — Get calendar events from the user’s connected calendars ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Claap MCP connector > Video collaboration platform for recording, sharing, and discussing async video clips — used for meeting recordings, product demos, feedback, and team... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'claapmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Claap MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'claapmcp_list_workspaces', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "claapmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Claap MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="claapmcp_list_workspaces", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update recording view, recording field, deal view** — Update an existing recording view (saved preset of meetings) * **List views, users, recording fields** — List the views (saved presets) of a Claap workspace across recordings (meetings), deals, companies and contacts, grouped by entity * **Get user, recording, deal view** — Get a single user of a Claap workspace by userId or email, with its id, name, email, state, license and role * **Create recording view, recording field, deal view** — Create a recording view (saved preset) in a Claap workspace * **Search recording transcripts, emails, deals** — Perform keyword or semantic search on the recording transcript database, with optional filters on the recording metadata ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Clari Copilot connector > Connect to Clari Copilot for sales call transcripts, analytics, call data, and insights. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'clari-copilot' 12 const identifier = 'user_123' 13 14 // Make your first API call through the proxy 15 const result = await actions.request({ 16 connectionName: connector, 17 identifier, 18 path: '/v1/users/me', 19 method: 'GET', 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "clari-copilot" 14 identifier = "user_123" 15 16 # Make your first API call through the proxy 17 result = actions.request( 18 connection_name=connection_name, 19 identifier=identifier, 20 path="/v1/users/me", 21 method="GET", 22 ) 23 print(result) ``` ## Common workflows [Section titled “Common workflows”](#common-workflows) --- # DOCUMENT BOUNDARY --- # Clarify MCP connector > Connect to Clarify MCP to manage CRM records, leads, campaigns, lists, and analytics directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'clarifymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Clarify MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'clarifymcp_get_agents', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "clarifymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Clarify MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="clarifymcp_get_agents", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Manage CRM records** — create, update, delete, and query records across any custom object type * **Manage campaigns** — create, update, delete, and list outreach campaigns with multi-step email sequences * **Find and import leads** — search for leads by criteria and import them into campaigns or lists * **Manage lists and segments** — create, update, delete, and list audience lists for targeting * **Extend the data model** — create, update, and delete custom objects and fields to match your schema * **Analyze and query data** — run analytics queries and retrieve structured data with custom filters ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Clay MCP connector > Clay is a go-to-market (GTM) platform that unifies data sourcing from 150+ providers, AI-powered research agents, and workflow orchestration for sales and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'claymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Clay MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'claymcp_get_credits_available', 25 toolInput: { rationale: 'YOUR_RATIONALE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "claymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Clay MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"rationale":"YOUR_RATIONALE"}, 27 tool_name="claymcp_get_credits_available", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get current workspace, task context, task** — Report which Clay workspace this connection is pinned to * **Event track** — Track an analytics event with optional properties * **Run subroutine no mapping, subroutine direct, subroutine** — Run a custom subroutine on search entities * **Query objects** — Query audience accounts, contacts, or deals using natural language * **List subroutines, find and enrich** — List available custom functions in the workspace * **Company find and enrich contacts at, find and enrich** — Search for contacts at a company by role, title, name, or department ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Clickhouse MCP connector > Connect to ClickHouse MCP to query, analyze, and manage your ClickHouse databases directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'clickhouse' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Clickhouse MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'clickhouse_get_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "clickhouse" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Clickhouse MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="clickhouse_get_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Run SELECT queries** — execute read-only SQL queries against any ClickHouse service and retrieve results directly in your agent * **Explore schema** — list databases, tables, and column types to understand your data model before writing queries * **Manage services** — list, inspect, and get full details for ClickHouse Cloud services (clusters) in an organization * **Monitor backups** — list service backups, get backup details, and retrieve the backup schedule and retention config * **Inspect ClickPipes** — list and retrieve data ingestion pipeline status and configuration * **Track costs** — get billing and usage cost data for an organization over a custom date range ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ClickUp connector > Connect to ClickUp. Manage tasks, projects, workspaces, and team collaboration 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your ClickUp credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'clickup' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ClickUp:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'clickup_user_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "clickup" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ClickUp:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="clickup_user_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Manage tasks** — create, update, delete, and search tasks; set priorities, due dates, assignees, and statuses * **Manage lists** — create, update, and delete lists in folders or as folderless lists; get members * **Manage folders** — create, update, and delete folders; list all folders in a space * **Manage spaces** — create, update, and delete spaces; manage space tags and views * **Manage comments** — add, update, and delete comments on tasks and lists * **Manage goals** — create, update, delete, and list goals and their key results * **Track time** — list and create time entries for tasks * **Manage checklists** — create task checklists and checklist items * **Manage webhooks** — create, update, delete, and list workspace webhooks * **Access workspace data** — get user info, list workspaces, spaces, and views ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ClickUp MCP connector > Connect to ClickUp MCP to manage tasks, projects, spaces, and workspaces directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'clickupmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ClickUp MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'clickupmcp_clickup_get_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "clickupmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ClickUp MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="clickupmcp_clickup_get_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update clickup** — Update task properties * **Tracking clickup stop time, clickup start time** — Stop the currently running time tracker * **Send clickup** — Send a message or threaded reply to a chat channel * **Search clickup** — Search and list your reminders * **Assignees clickup resolve** — Convert names, emails, or “me” to numeric ClickUp user IDs * **Upload clickup request attachment** — Get short-lived, structured upload details (upload URL, ticket, HTTP method, and multipart field name) to attach a LOCAL file (any size) to a task; follow the returned instructions to upload it with a native HTTP client ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Close connector > Connect to Close CRM. Manage leads, contacts, opportunities, tasks, activities, and sales workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Close credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'close' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Close:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'close_activities_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "close" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Close:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="close_activities_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tasks bulk, smart view, sequence** — Bulk-update assigned\_to, date, or is\_complete across every task matching the given filters * **List smart views, opportunity statuses, lead statuses** — List Smart Views (saved searches) in Close * **Get smart view, report activity, webhook** — Retrieve a single Smart View (saved search) by ID from Close, including its stored query definition and sharing settings * **Delete smart view, sequence subscription, sequence** — Permanently delete a Smart View (saved search) from Close * **Create smart view, sequence, field enrichment** — Create a new Smart View (saved search) in Close * **Merge lead** — Merge two leads into one ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Close MCP connector > Close is a CRM and sales platform. The Close MCP server provides a standardized interface that allows any compatible AI model or agent to access Close CRM... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'closemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Close MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'closemcp_activity_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "closemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Close MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="closemcp_activity_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update draft email, custom object instance, call task** — Update an existing draft email * **Instances find custom object, find custom activity** — Find a lead’s custom object instances * **Tasks find call, find** — Find call tasks based on various filters * **Fetch meeting transcript, custom object instance, call task** — Fetch a meeting’s Notetaker transcript(s) by meeting activity ID * **Delete custom object instance, call task, task** — Permanently delete an existing custom object instance * **Labels customized builtin** — Return the customized builtin labels ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Cloudflare MCP connector > Connect to Cloudflare MCP to manage your Cloudflare account — execute API calls, search the OpenAPI spec, and interact with Workers, R2, D1, KV, and all... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'cloudfaremcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Cloudflare MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'cloudfaremcp_search', 25 toolInput: { code: 'YOUR_CODE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "cloudfaremcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Cloudflare MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"code":"YOUR_CODE"}, 27 tool_name="cloudfaremcp_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Docs records** — Search the Cloudflare documentation * **Search records** — Search the Cloudflare OpenAPI spec to discover API endpoints, request parameters, and response schemas * **Execute records** — Execute JavaScript code against the Cloudflare API using the `cloudflare.request()` helper ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Cloudflare connector > Cloudflare is a cloud platform providing DNS management, CDN, security, and networking services. This connector enables automated management of zones, DNS... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Cloudflare credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'cloudflare' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Cloudflare:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'cloudflare_account_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "cloudflare" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Cloudflare:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="cloudflare_account_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update zone setting, ruleset entrypoint, dns record** — Change the value of a single zone setting, such as ssl, always\_use\_https, min\_tls\_version, security\_level, or cache\_level * **Get zone setting, zone, worker script** — Retrieve the current value of a single zone setting, such as ssl, always\_use\_https, min\_tls\_version, security\_level, or cache\_level * **Cache zone purge** — Purge cached content for a Cloudflare zone * **Create zone, worker route, page rule** — Add a new domain (zone) to a Cloudflare account * **Dashboard zone analytics** — Retrieve aggregate traffic analytics for a Cloudflare zone: requests, bandwidth, threats, and cache statistics over a time window * **Delete worker script, dns record, access application** — Permanently delete a Cloudflare Worker script by name ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Cloudinary MCP connector > Connects AI agents to Cloudinary's asset management platform, enabling upload, search, transformation, and organization of media assets through natural... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'cloudinarymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Cloudinary MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'cloudinarymcp_get_tx_reference', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "cloudinarymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Cloudinary MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="cloudinarymcp_get_tx_reference", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Upload sign** — Use this tool when the user wants to upload a file to Cloudinary directly from their own machine or environment * **Tags manage asset** — Adds, removes, or replaces tags on multiple assets Applies a tag command to the given assets, addressing them by public ID * **Metadata manage asset** — Sets structured metadata values on multiple assets Assigns structured metadata field values to the given assets, addressing them by public ID * **Context manage asset** — Adds or clears contextual metadata on multiple assets Applies a contextual-metadata command to the given assets, addressing them by public ID * **Get generation task, usage details, tx reference** — Get a generation task Get the status of a generation task * **Images generate image from** — Generate an image from reference images Generate an image guided by one or more **reference images** — restyle, on-brand variants, character consistency, virtual try-on, edit/extend — steered by `prompt` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Cloudpress MCP connector > Cloudpress is a managed WordPress hosting platform built for the AI era. Its MCP server lets AI agents manage sites, domains, DNS, security rules... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'cloudpressmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Cloudpress MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'cloudpressmcp_list_dns_zones', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "cloudpressmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Cloudpress MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="cloudpressmcp_list_dns_zones", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List site tasks, waf managed rules, waf custom rules** — List a site’s task/activity history, most recent first * **Update waf custom rule, shield, rate limit** — Update a custom WAF rule (full replace of its configuration) * **Rule toggle edge** — Enable or disable an edge rule without deleting it * **Domains suggest** — Get alternate/related available domain name suggestions for a base name, each with its orderable price * **Search domains** — Search domain availability for a base name across every orderable TLD, with create and transfer pricing * **Site restart, rename** — Asynchronously restart a Cloudpress site’s container ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Cognee connector > Connect to Cognee, an AI memory engine for agents. Remember data into a knowledge graph, recall it with semantic search, improve stored memory, and forget... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Cognee credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'cognee' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'cognee_check_status', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "cognee" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="cognee_check_status", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Visualize records** — Generate a human-viewable HTML visualization of a dataset’s knowledge graph — an interactive page with nodes and edges — distinct from Get dataset graph, which returns the raw node/edge JSON * **Ingest skill** — Ingest a reusable skill from inline SKILL.md markdown text, without uploading a file * **Entry remember** — Store a single typed memory entry directly into the session cache (or, for skill runs, the permanent graph), bypassing the bulk ingest+cognify flow used by Improve/Remember * **History recall** — Get the authenticated user’s history of prior recall (search) queries and results, each with id, text, user, and created\_at * **Delete ontology** — Delete an uploaded OWL ontology by its key, exactly as provided at upload time * **List ontologies, datasets, dataset data** — List the OWL ontology files uploaded to this Cognee account ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # CoinMarketCap MCP connector > Connect to CoinMarketCap MCP. Access real-time crypto quotes, market metrics, technical analysis, trending narratives, and news from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'coinmarketcapmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize CoinMarketCap MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'coinmarketcapmcp_get_crypto_marketcap_technical_analysis', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "coinmarketcapmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize CoinMarketCap MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="coinmarketcapmcp_get_crypto_marketcap_technical_analysis", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Skill find** — Search the platform’s skill library for hosted data and analysis services covering crypto markets and prediction/event markets * **Execute skill** — Run a specific platform skill by its unique name and return structured results * **Narratives trending crypto** — Get a ranked list of the top trending cryptocurrency narratives, including market cap, trading volume, performance across timeframes, and the top associated tokens * **Search cryptos, crypto info** — Search cryptocurrencies by name, symbol, or slug using fuzzy matching * **Get upcoming macro events, global metrics latest, global crypto derivatives metrics** — Get a list of upcoming macroeconomic events that could impact the crypto market, useful for anticipating price catalysts ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Commonroom MCP connector > Connect to Common Room MCP to manage community members, objects, and feedback data directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Commonroom MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'commonroommcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Commonroom MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'commonroommcp_commonroom_get_catalog', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "commonroommcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Commonroom MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="commonroommcp_commonroom_get_catalog", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update commonroom** — Update fields on an existing Common Room object (contact, organization, segment, etc.) by its ID * **Feedback commonroom submit** — Submit feedback on the quality of a query result — use after presenting data to the user * **List commonroom** — List Common Room objects (contacts, organizations, segments, etc.) with optional pagination, filtering, and sorting * **Get commonroom** — Retrieve the catalog of available object types, their properties, and allowed sort fields in Common Room * **Create commonroom** — Create a new object in Common Room — contact, organization, activity, or custom object type ## Common workflows [Section titled “Common workflows”](#common-workflows) ### List community members Use `commonroommcp_commonroom_list_objects` with `objectType` set to `Contact` to retrieve community members with optional filtering and pagination. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'commonroommcp', 3 identifier: 'user_123', 4 toolName: 'commonroommcp_commonroom_list_objects', 5 toolInput: { 6 objectType: 'Contact', 7 limit: 20, 8 }, 9 }); 10 console.log(result); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="commonroommcp", 3 identifier="user_123", 4 tool_name="commonroommcp_commonroom_list_objects", 5 tool_input={ 6 "objectType": "Contact", 7 "limit": 20, 8 }, 9 ) 10 print(result) ``` ### Create a contact Use `commonroommcp_commonroom_create_object` to add a new contact to your Common Room community. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'commonroommcp', 3 identifier: 'user_123', 4 toolName: 'commonroommcp_commonroom_create_object', 5 toolInput: { 6 objectType: 'Contact', 7 email: 'alex@example.com', 8 fullName: 'Alex Johnson', 9 title: 'Senior Engineer', 10 companyName: 'Example Corp', 11 }, 12 }); 13 console.log(result); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="commonroommcp", 3 identifier="user_123", 4 tool_name="commonroommcp_commonroom_create_object", 5 tool_input={ 6 "objectType": "Contact", 7 "email": "alex@example.com", 8 "fullName": "Alex Johnson", 9 "title": "Senior Engineer", 10 "companyName": "Example Corp", 11 }, 12 ) 13 print(result) ``` ### Discover available object types Use `commonroommcp_commonroom_get_catalog` to retrieve the full list of object types, their properties, and allowed sort fields before querying or creating objects. * Node.js ```typescript 1 const catalog = await actions.executeTool({ 2 connectionName: 'commonroommcp', 3 identifier: 'user_123', 4 toolName: 'commonroommcp_commonroom_get_catalog', 5 toolInput: {}, 6 }); 7 console.log(catalog); ``` * Python ```python 1 catalog = actions.execute_tool( 2 connection_name="commonroommcp", 3 identifier="user_123", 4 tool_name="commonroommcp_commonroom_get_catalog", 5 tool_input={}, 6 ) 7 print(catalog) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Confluence connector > Connect to Confluence. Manage spaces, pages, content, and team collaboration 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Confluence credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'confluence' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Confluence:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'confluence_attachments_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "confluence" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Confluence:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="confluence_attachments_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update space property, page property, page classification level** — Update an existing content property on a Confluence space * **List space property, space permissions, page property** — List the content properties (custom key/value metadata) attached to a Confluence space * **Get space property, space permission assignments, space operations** — Retrieve a specific content property attached to a Confluence space by its property ID * **Delete space property, smart link, page property** — Delete a content property from a Confluence space by its property ID * **Create space property, smart link, page property** — Create a new content property (custom key/value metadata) on a Confluence space * **Redact page, blogpost** — Redact sensitive content in a Confluence page by replacing specified text ranges in the body and/or title with redaction markers ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Contentful MCP connector > Connect to Contentful MCP. Manage spaces, entries, assets, content types, and taxonomies in your Contentful CMS from AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'contentfulmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Contentful MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'contentfulmcp_get_initial_context', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "contentfulmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Contentful MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="contentfulmcp_get_initial_context", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search semantic, entries** — Find entries by meaning using semantic (vector) search * **References resolve entry** — Recursively resolve an entry’s references and return the entry plus its descendant entries and linked assets, without issuing one fetch per descendant * **Field omit content type, disable content type, append entry** — Mark a single content type field as omitted (or un-omitted) from API responses * **Get entry snapshot, space, org** — Retrieve version history (snapshots) of an entry for safe rollback * **Delete content type field, locale, environment** — Permanently mark a single content type field as deleted * **Asset upload, unpublish, unarchive** — Upload a new asset to Contentful from a URL or file handle ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Context7 MCP connector > Connect to Context7 MCP to fetch up-to-date, version-specific library documentation and code examples directly from the source. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Context7 MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'context7mcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'context7mcp_query_docs', 19 toolInput: { libraryId: 'YOUR_LIBRARYID', query: 'YOUR_QUERY' }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "context7mcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"libraryId":"YOUR_LIBRARYID","query":"YOUR_QUERY"}, 19 tool_name="context7mcp_query_docs", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Id resolve library** — Resolves a package/product name to a Context7-compatible library ID and returns matching libraries * **Query docs** — Retrieves and queries up-to-date documentation and code examples from Context7 for any programming library or framework ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Conversion Tools MCP connector > Connect to Conversion Tools MCP. Convert files between 140+ formats including documents, images, audio, video, and data files from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'conversiontoolsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Conversion Tools MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'conversiontoolsmcp_auth_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "conversiontoolsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Conversion Tools MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="conversiontoolsmcp_auth_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Run studio** — Poll the status of an AI Studio converter run started with studio\_run * **List studio, parse, converters** — List the custom converters previously built in AI Studio for the signed-in account, so an existing converter can be reused instead of rebuilding one * **Get studio, download url, converter info** — Get a custom AI Studio converter’s details and current status, including its input/output shape and the file currently attached * **Result studio download** — Download the result of a successful AI Studio converter run, using the result\_file\_id from studio\_run\_status * **Create studio, parse** — Start building a new custom converter with AI Studio, for conversions that need engines not available locally, large or sensitive files, multi-step transformations, or a durable reusable converter * **Chat studio** — Send a plain-language build instruction to the AI Studio planner for a converter created with studio\_create\_converter ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ConvertAPI MCP connector > Connect to ConvertAPI MCP. Convert, merge, split, and transform files across 200+ formats including PDF, Word, Excel, images, and more. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'convertapimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ConvertAPI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'convertapimcp_get_converters_by_tags', 25 toolInput: { tags: [] }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "convertapimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ConvertAPI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"tags":[]}, 27 tool_name="convertapimcp_get_converters_by_tags", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search converters** — Search for available ConvertAPI converters that match the specified search terms * **Url request upload** — Generate a curl command to upload a local file to ConvertAPI and obtain a FileId * **Get converters by tags, conversion parameters** — Retrieve a list of available ConvertAPI converters that match all specified tags * **Convert records** — Convert a file from one format to another using ConvertAPI ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Crossbeam MCP connector > Connect to Crossbeam MCP. Discover partner account overlaps, surface ecosystem activity, get partner and account context, and access co-selling... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'crossbeammcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Crossbeam MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'crossbeammcp_find_overlaps', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "crossbeammcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Crossbeam MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="crossbeammcp_find_overlaps", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search crossbeam knowledge** — Answer Crossbeam product questions and surface best practices from the Crossbeam knowledge base * **Get partner suggestions, partner context, list link** — Surface potential new partners based on ecosystem fit, helping expand your partner network * **Recommendations find partner** — Return ranked partner suggestions for an open opportunity, helping identify which partners can best assist with a deal * **Overlaps find** — Pull a list of accounts you share with one or more partners * **Partners find overlap** — Identify which partners have a given account in their data, revealing who can help with a specific company ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Crustdata MCP connector > People and company intelligence platform for candidate sourcing, sales prospecting, and talent intelligence. Provides real-time data on professionals... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'crustdatamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Crustdata MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'crustdatamcp_crustdata_credits_check', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "crustdatamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Crustdata MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="crustdatamcp_crustdata_credits_check", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search crustdata web, crustdata people, crustdata company** — WEB SEARCH on the v2 API (version 2025-11-01) * **Fetch crustdata web** — WEB FETCH on the v2 API (version 2025-11-01) * **Update crustdata watch, crustdata watcher** — WATCH UPDATE — NEW watcher system (v2025-11-01 API) * **List crustdata watch, crustdata watcher, crustdata** — WATCH LIST — NEW watcher system (v2025-11-01 API) * **Get crustdata watch, crustdata watcher, crustdata** — WATCH GET — NEW watcher system (v2025-11-01 API) * **Create crustdata watch, crustdata watcher** — WATCH CREATE — NEW watcher system (v2025-11-01 API) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Customer.io MCP connector > Connect to Customer.io MCP to manage customers, campaigns, and events 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Customer.io MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'customeriomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Customer.io MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'customeriomcp_cio_auth_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "customeriomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Customer.io MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="customeriomcp_cio_auth_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Api cio write** — Write to the Customer.io API (POST, PUT, or PATCH) * **Read cio skills, cio** — Read the full content of a specific Customer.io agent skill by path * **List cio skills** — List available Customer.io agent skills — task-specific instruction manuals covering campaigns, segments, deliveries, analytics, and more * **Schema cio** — Introspect the Customer.io API schema to discover endpoints, parameters, and response shapes * **Prime cio** — Print LLM-ready instructions for using the Customer.io API * **Delete cio** — Delete a resource via the Customer.io API (DELETE only) ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Check authentication status Use `customeriomcp_cio_auth_status` to verify the connection and see the authenticated user, account, and accessible workspaces. * Node.js ```typescript 1 const status = await actions.executeTool({ 2 connectionName: 'customeriomcp', 3 identifier: 'user_123', 4 toolName: 'customeriomcp_cio_auth_status', 5 toolInput: {}, 6 }); 7 console.log(status); ``` * Python ```python 1 status = actions.execute_tool( 2 connection_name="customeriomcp", 3 identifier="user_123", 4 tool_name="customeriomcp_cio_auth_status", 5 tool_input={}, 6 ) 7 print(status) ``` ### Read campaign data Use `customeriomcp_cio_read_api` to fetch campaigns from a Customer.io environment. Call `customeriomcp_cio_schema` first to discover the correct API path and available parameters. * Node.js ```typescript 1 const campaigns = await actions.executeTool({ 2 connectionName: 'customeriomcp', 3 identifier: 'user_123', 4 toolName: 'customeriomcp_cio_read_api', 5 toolInput: { 6 path: '/v1/environments/{environment_id}/campaigns', 7 params: { environment_id: 'env_abc123' }, 8 limit: 10, 9 }, 10 }); 11 console.log(campaigns); ``` * Python ```python 1 campaigns = actions.execute_tool( 2 connection_name="customeriomcp", 3 identifier="user_123", 4 tool_name="customeriomcp_cio_read_api", 5 tool_input={ 6 "path": "/v1/environments/{environment_id}/campaigns", 7 "params": {"environment_id": "env_abc123"}, 8 "limit": 10, 9 }, 10 ) 11 print(campaigns) ``` ### Create a campaign Use `customeriomcp_cio_write_api` to create a new campaign. Always set `dry_run: true` first to validate the request before executing. * Node.js ```typescript 1 // Step 1 — dry run to validate 2 const preview = await actions.executeTool({ 3 connectionName: 'customeriomcp', 4 identifier: 'user_123', 5 toolName: 'customeriomcp_cio_write_api', 6 toolInput: { 7 path: '/v1/environments/{environment_id}/campaigns', 8 params: { environment_id: 'env_abc123' }, 9 body: { name: 'Welcome Series', type: 'triggered' }, 10 dry_run: true, 11 }, 12 }); 13 console.log(preview); 14 15 // Step 2 — execute after confirming dry run looks correct 16 const result = await actions.executeTool({ 17 connectionName: 'customeriomcp', 18 identifier: 'user_123', 19 toolName: 'customeriomcp_cio_write_api', 20 toolInput: { 21 path: '/v1/environments/{environment_id}/campaigns', 22 params: { environment_id: 'env_abc123' }, 23 body: { name: 'Welcome Series', type: 'triggered' }, 24 }, 25 }); 26 console.log(result); ``` * Python ```python 1 # Step 1 — dry run to validate 2 preview = actions.execute_tool( 3 connection_name="customeriomcp", 4 identifier="user_123", 5 tool_name="customeriomcp_cio_write_api", 6 tool_input={ 7 "path": "/v1/environments/{environment_id}/campaigns", 8 "params": {"environment_id": "env_abc123"}, 9 "body": {"name": "Welcome Series", "type": "triggered"}, 10 "dry_run": True, 11 }, 12 ) 13 print(preview) 14 15 # Step 2 — execute after confirming dry run looks correct 16 result = actions.execute_tool( 17 connection_name="customeriomcp", 18 identifier="user_123", 19 tool_name="customeriomcp_cio_write_api", 20 tool_input={ 21 "path": "/v1/environments/{environment_id}/campaigns", 22 "params": {"environment_id": "env_abc123"}, 23 "body": {"name": "Welcome Series", "type": "triggered"}, 24 }, 25 ) 26 print(result) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SMART App on FHIR connector > SMART App on FHIR is a healthcare interoperability provider that enables secure access to electronic health records and clinical data using the SMART on... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your SMART App on FHIR credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update goal, document reference, care team** — Update an existing FHIR Goal resource by its ID * **Search goal, document reference, care team** — Search for FHIR Goal resources using parameters like patient, lifecycle status, and target date * **Read goal, document reference, care team** — Retrieve a single FHIR Goal resource by its logical ID * **Delete goal, document reference, care team** — Delete a FHIR Goal resource by its logical ID * **Create goal, document reference, care team** — Create a new FHIR Goal resource for a patient describing a target health outcome with a lifecycle status, description, category, and target due date * **Everything patient** — Invoke the $everything operation on a Patient to retrieve all clinical resources associated with that patient in a single Bundle response ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dart AI MCP connector > AI-native project management tool for task and document management with deep AI integration. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dartaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Dart AI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'dartaimcp_get_config', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dartaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Dart AI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="dartaimcp_get_config", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update task description, task, doc text** — Apply targeted text updates to a task’s description * **Title retrieve skill by** — Retrieve a skill by its title * **Issue report** — Create a concise markdown issue report for Dart Support * **Task move** — Move a task to a specific position by placing it before or after another task * **List tasks, help center articles, docs** — List tasks with powerful filtering options * **Get view, task, folder** — Retrieve an existing view by its ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Databox MCP connector > Connect to Databox MCP. Query metrics, manage dashboards, and push custom data to your Databox analytics and reporting platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'databoxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Databox MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'databoxmcp_get_current_datetime', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "databoxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Databox MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="databoxmcp_get_current_datetime", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search databoards** — Search Databox databoards (dashboards) by text query, optionally filtered by data source type or by connection/space access ID * **Data refresh chart, load metric, ingest** — Fetch chart-ready data for a Databox visualization given a metric setup, date range, and visualization type (line, bar, or table), with optional filters * **Get date ranges, databoard by id, ingestion** — Resolve a JSON-encoded SimpleDateRange object (e.g * **List metrics, merged datasets, data sources** — List all metrics available for a Databox data source, including metric keys, names, descriptions, and available dimensions * **Delete dataset, data source** — Permanently delete a dataset and all its data from Databox * **Create dataset, data source** — Create a structured dataset within a Databox data source, optionally defining a column schema and primary keys for tabular data storage ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Databricks Workspace connector > Connect to Databricks Workspace APIs using a Service Principal with OAuth 2.0 client credentials to manage clusters, jobs, notebooks, SQL, and more. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List workspace, secrets, repos** — List the contents (notebooks, folders, libraries) of a Databricks workspace directory * **Import workspace** — Import a notebook into the Databricks workspace from base64-encoded content * **Get workspace, permissions, sql statement result chunk** — Get metadata about a Databricks workspace object (notebook, folder, or file), including its object type, language, and object ID * **Export workspace** — Export a Databricks notebook or directory * **Delete workspace, secret, repo** — Permanently delete a notebook or directory from the Databricks workspace * **Create secret scope, repo, job** — Create a new secret scope in the Databricks workspace, backed by Databricks or an Azure Key Vault ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Datadog connector > Connect to Datadog to monitor metrics, logs, traces, dashboards, monitors, incidents, SLOs, synthetics, and security signals across your infrastructure. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Datadog credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'datadog' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'datadog_containers_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "datadog" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="datadog_containers_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create user invitation, team, synthetics private location** — Send or resend a Datadog organization invitation email to an existing user * **List teams, team memberships, slo correction** — List all Datadog teams, with optional keyword search and pagination * **Update team, slo correction, metric tag configuration** — Update a Datadog team by ID * **Remove team membership** — Remove a user from a Datadog team * **Add team membership** — Add a user to a Datadog team * **Get team, slo correction, synthetics browser test** — Get a specific Datadog team by ID ## Common workflows [Section titled “Common workflows”](#common-workflows) Downtime response includes two IDs The `downtime_create` response contains both `data.id` (the downtime UUID) and `included[].id` (the creator’s user UUID). Always use `data.id` for subsequent `downtime_get`, `downtime_update`, and `downtime_cancel` calls. ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most tools require IDs that must be fetched from the API — never guess or hard-code them. | Resource | Tool to get ID | Field in response | | --------------- | ---------------------------------- | ------------------------------------------------------------ | | Monitor ID | `datadog_monitors_list` | `array[].id` | | Dashboard ID | `datadog_dashboards_list` | `dashboards[].id` | | Downtime ID | `datadog_downtime_create` response | `data.id` (UUID — not `included[].id`) | | Notebook ID | `datadog_notebooks_list` | `data[].id` | | Incident ID | `datadog_incidents_list` | `data[].id` | | SLO ID | `datadog_slos_list` | `data[].id` | | Role ID | `datadog_roles_list` | `data[].id` | | User ID | `datadog_users_list` | `data[].id` | | RUM App ID | `datadog_rum_applications_list` | `data[].id` | | Event ID | `datadog_event_create` response | `event.id_str` (**use `id_str`, not `id`** — see note below) | | Metric name | `datadog_metrics_list` | `metrics[]` (requires `from` Unix timestamp) | | Log pipeline ID | `datadog_log_pipelines_list` | `array[].id` | ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dataforseo MCP connector > Connect to DataForSEO. Access real-time SEO data including SERP results, keyword analytics, backlinks analysis, domain technologies, and AI visibility... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dataforseomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Dataforseo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'dataforseomcp_business_data_business_listings_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dataforseomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Dataforseo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="dataforseomcp_business_data_business_listings_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Serps dataforseo labs google historical** — Get historical Google SERP results for a keyword within a specified date range * **Keywords dataforseo labs amazon related, dataforseo labs amazon ranked, dataforseo labs google related** — Get related keywords from Amazon’s “Related Searches” section for a seed keyword * **Overview dataforseo labs amazon product rank, domain analytics whois, dataforseo labs google keyword** — Get organic and paid Amazon SERP ranking data for a list of target ASINs * **Intersections dataforseo labs amazon product kw** — Find keywords for which multiple target Amazon products (ASINs) intersect in Amazon SERP results * **Competitors dataforseo labs amazon product, dataforseo labs google serp, backlinks** — Find Amazon products that intersect with a target ASIN in Amazon SERPs to identify product competitors * **Search dataforseo labs amazon bulk, kw data google ads, dataforseo labs** — Get Amazon search volume data for up to 1,000 keywords in a single request ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Deel MCP connector > Global HR and payroll platform for hiring, paying, and managing international employees and contractors with built-in compliance. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'deelmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Deel MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'deelmcp_advance_eligibility_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "deelmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Deel MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="deelmcp_advance_eligibility_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List payment request, goal, goal cycle** — Returns the last N payment requests for the authenticated employee profile, including amount, currency, status, due dates, and activity logs * **Update goal, goal progress, worker relation type external id** — Partially updates an existing goal * **Create goal, timesheet root preset async, timesheet preset** — Creates a new goal and returns its ID and title * **Trigger workflow, workflow action** — Creates an internal invisible workflow with a trigger * **Get worker personal info external, verification method, verification kyc** — Retrieves a worker profile record using a system-wide external worker identifier * **Download worker document, invoice, gp payslip** — Get the download link of worker document ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Deepgram MCP connector > Connect to Deepgram MCP. Transcribe audio, generate speech, and manage transcription projects using Deepgram's AI-powered speech recognition API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'deepgrammcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Deepgram MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'deepgrammcp_search_deepgram_knowledge_sources', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "deepgrammcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Deepgram MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="deepgrammcp_search_deepgram_knowledge_sources", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search deepgram knowledge sources** — Search Deepgram documentation and knowledge sources for the most relevant results for a given query ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # DeepL MCP connector > Connect to DeepL's MCP server to translate and rephrase text, correct grammar, translate documents, and manage glossaries and writing styles. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'deeplmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize DeepL MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'deeplmcp_get_source_languages', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "deeplmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize DeepL MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="deeplmcp_get_source_languages", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Document upload, download** — Translate a whole file or document, preserving its original layout and formatting * **Text translate, rephrase, correct** — Translate text to a target language using DeepL * **Get target languages, source languages, document status** — Get the target language codes supported by DeepL for translation, e.g ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # DeepWiki connector > Connect to DeepWiki MCP to ask questions about and read AI-generated documentation for public GitHub repositories directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read wiki structure, wiki contents** — Get a list of documentation topics for a GitHub repository * **Question ask** — Ask any question about a GitHub repository and get an AI-powered, context-grounded response ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Descript MCP connector > Connect to Descript MCP. Import media, export transcripts, publish projects, run AI editing agents, and manage jobs from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'descriptmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Descript MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'descriptmcp_get_drive_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "descriptmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Descript MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="descriptmcp_get_drive_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Status report upload** — Report that a direct upload failed, was aborted, or was abandoned so the import job stops waiting on that file * **List folders, projects, jobs** — List folders in the Descript drive, optionally scoped to a parent folder * **Media import drive, import** — Import media files into the Descript drive media library (not a project) via URLs or direct file upload * **Get drive info, project** — Return the Descript drive (workspace) connected to the current session, including its ID and name * **Timeline export** — Export a project composition as a timeline file (AAF, SESX, EDL, FCPXML, Premiere XML, or DaVinci Resolve XML) for import into another DAW/NLE * **Job wait for, cancel** — Poll a Descript job until it completes, streaming progress updates, with an optional timeout ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Devin MCP connector > Connect to Devin MCP. Create and manage AI coding sessions, interact with Devin agents, manage playbooks and schedules, and browse repository wikis from... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Devin MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'devinmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'devinmcp_devin_session_search', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "devinmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="devinmcp_devin_session_search", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Setting find** — Find a Devin webapp setting and get a deep-link URL to it * **Manage devin review, devin oncall, devin code scan** — Trigger a Devin Review for a pull/merge request, or fetch its latest review status * **Read wiki structure, wiki contents** — Get a list of documentation topics for a GitHub repository * **List integrations, available repos** — List all native integrations and MCP servers for the organization with status and settings * **Wiki generate** — Generate a codebase wiki for a repository and wait for it to complete * **Search devin session** — Search and filter Devin sessions by date, tags, playbook, schedule, or user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dev Rev MCP connector > Connect to DevRev MCP. Manage issues, work items, conversations, and customer data in the DevRev product development platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Dev Rev MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'devrevmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'devrevmcp_get_self', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "devrevmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="devrevmcp_get_self", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update object** — Update fields on an existing DevRev object using a specified update action * **List objects** — List DevRev objects (issues, tickets, etc.) with optional filters using a specified list action * **Objects link** — Create a link between two DevRev objects using a specified link action * **Search hybrid** — Search across DevRev’s knowledge graph using natural language to find issues, tickets, articles, and other objects * **Get valid stage transitions, tool metadata, sprint board** — Return valid stage transitions for a given DevRev object type and its current stage * **Fetch object context** — Fetch contextual information about any DevRev object by its DON ID or display ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Diarize connector > Connect to Diarize to transcribe and diarize audio and video content from YouTube, X, Instagram, and TikTok. Submit transcription jobs and retrieve... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Diarize credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'diarize' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'diarize_get_job_status', 19 toolInput: { job_id: 'YOUR_JOB_ID' }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "diarize" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"job_id":"YOUR_JOB_ID"}, 19 tool_name="diarize_get_job_status", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get job status** — Retrieve the current status of a transcription job by its job ID * **Transcript download** — Download the transcript output for a completed transcription job in JSON, TXT, SRT, or VTT format, including speaker diarization, segments, and word-level timestamps * **Create transcription job** — Submit a new transcription and diarization job for an audio or video URL (YouTube, X, Instagram, TikTok) ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Digits MCP connector > Digits is an AI-powered business finance platform. This MCP connector gives AI agents read-only access to your Digits data — transactions, financial... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'digitsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Digits MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'digitsmcp_list_businesses', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "digitsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Digits MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="digitsmcp_list_businesses", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Delete transactions** — Delete one or more transactions for a business by their transaction fact IDs * **Create transactions** — Create one or more manual journal-entry transactions (double-entry bookkeeping records) for a business in a single atomic batch * **Business select** — Select a business to work with * **Search term** — Resolve a customer, vendor, category, department, location name or transaction description to its canonical form using fuzzy text matching * **Query transactions** — Query and filter individual transactions * **List locations, departments, categories** — This tool is used to list locations ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Discord connector > Connect to Discord. Read user profile, guilds, roles, manage bots, and perform interactions. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Discord credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'discord' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Discord:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'discord_get_gateway', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "discord" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Discord:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="discord_get_gateway", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update current user application role connection** — Updates and returns the application role connection for the current user and the given application * **Send lobby message** — Send a message to a Discord lobby * **List sku subscriptions, guild channels, my guilds** — Retrieve all subscriptions containing a given SKU, filtered by user * **Lobby link channel to, leave** — Link an existing guild text channel to a Discord lobby, or unlink any currently linked channel by omitting channel\_id * **Get sku subscription, lobby messages, guild application command permissions** — Retrieve a single subscription for a SKU by its ID * **Permissions edit application command** — Edit the permissions for a specific application command in a guild ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Discord Bot connector > Connect to Discord as a bot. Manage guilds, channels, members, messages, roles, webhooks, and more using a Discord Bot Token. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Discord Bot credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'discordbot' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'discordbot_get_bot_gateway', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "discordbot" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="discordbot_get_bot_gateway", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update invite target users, lobby message moderation metadata, application role connection metadata** — Update the users allowed to see and accept an existing invite * **Search threads, guild messages, guild members** — Search for threads in a forum or media channel by name, applied tags, archive state, and other filters * **Invite resolve** — Resolve a Discord invite code to its invite object, including the associated guild, channel, and inviter * **List sticker packs, entitlements, current user guilds** — Retrieve all default Discord sticker packs (the packs available to Nitro subscribers), including each pack’s name, description, stickers, cover sticker, and banner asset * **Get guild widget png, guild widget, guild template** — Retrieve a PNG image widget for a Discord guild — a visual banner that can be embedded on external websites to show live member counts and an invite link * **Create guild sticker, webhook, test entitlement** — Create a new sticker for the guild ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Docsautomator MCP connector > Connect to DocsAutomator MCP. Generate documents and PDFs from templates using your data, automating document creation workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'docsautomatormcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Docsautomator MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'docsautomatormcp_get_queue_stats', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "docsautomatormcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Docsautomator MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="docsautomatormcp_get_queue_stats", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update automation esignature, automation** — Update the e-signature configuration of an automation: enable/disable signing, set signers, customize email templates and language, configure save-to-Drive * **Send test email** — Send a test email with a sample PDF to verify email configuration * **Invite resend esign** — Resend the signing invitation email to a specific signer * **Complete poll job until** — Poll a job until it completes or times out * **List placeholders, esign sessions, automations** — Extract all placeholders from a Google Doc template * **Get signing links, queue stats, job status** — Get signing links for all signers in a session ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dovetail MCP connector > Connect to Dovetail, the AI-native UX research platform. Access projects, insights, and data from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dovetailmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'dovetailmcp_get_dovetail_projects', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dovetailmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="dovetailmcp_get_dovetail_projects", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search workspace** — Perform powerful text-based search across all content types in the Dovetail workspace — projects, docs, data, highlights, and contacts * **List users, tags, project templates** — List all members of the Dovetail workspace, including their roles and contact information * **Get user, tag, project insight** — Retrieve a single workspace member’s profile by their unique identifier * **File download** — Get a short-lived presigned URL to download the raw content of a file attachment * **Create transcript highlight, tag, project** — Create a highlight on an audio or video transcript by marking a start/end time range in seconds ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dropbox connector > Connect to Dropbox. Manage files, folders, sharing, and cloud storage workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Dropbox credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dropbox' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Dropbox:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'dropbox_file_requests_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dropbox" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Dropbox:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="dropbox_file_requests_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get users, sharing, files** — Retrieve basic account information (name, profile photo, team membership) for any Dropbox user by their account ID * **Update sharing, file requests** — Change the access level of an existing member of a Dropbox shared folder, identified by email address * **Folder sharing unshare, sharing unmount, sharing mount** — Stop sharing a folder that the current Dropbox user owns * **File sharing unshare** — Remove all members from a Dropbox file and turn off its sharing, reverting it to a normal unshared file * **Member sharing remove folder, sharing remove file, sharing add file** — Remove a member (by email) from a Dropbox shared folder, revoking their access * **Settings sharing modify shared link** — Change the visibility, audience, or access settings of an existing Dropbox shared link, or remove its expiration ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dropbox MCP connector > Connect to Dropbox. Manage files and folders, create shared links, search content, and handle file requests from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Dropbox MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dropboxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Dropbox MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'dropboxmcp_check_job_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dropboxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Dropbox MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="dropboxmcp_check_job_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Folder restore** — Restore a folder to a previous point in time in Dropbox * **Revision restore file** — Restore a file to a previous revision in Dropbox * **List restore events, file revisions, shared links** — List restorable file and folder history events in Dropbox, optionally scoped to a path * **Get transcript, markdown, usage and quota** — Transcribe a Dropbox audio or video file, optionally polling an in-progress async transcription job * **I who am** — Retrieve the current Dropbox account profile information * **Search records** — Search for files and folders in Dropbox by query with optional filters ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dropcontact MCP connector > B2B contact enrichment and email verification platform that finds, verifies, and enriches professional email addresses and company data. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dropcontactmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Dropcontact MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'dropcontactmcp_check_credits', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dropcontactmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Dropcontact MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="dropcontactmcp_check_credits", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Validation submit email** — Submit an email validation request to check whether an email address is valid and deliverable * **Name submit contact enrichment by, submit contact enrichment by full** — Submit a contact enrichment request using first name, last name, and company name * **Linkedin submit contact enrichment by** — Submit a contact enrichment request using a LinkedIn profile URL * **Result retrieve enrichment** — Retrieve the result of a previously submitted enrichment or email validation request * **Credits check** — Check the number of remaining Dropcontact enrichment credits for the authenticated user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Dynamo Software connector > Connect to Dynamo Software API to access investment management, CRM, and reporting data. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'dynamo' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'dynamo_get_document_extended_schema', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "dynamo" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="dynamo_get_document_extended_schema", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Delete document, entity, bulk** — Deletes a single Dynamo document by ID * **Search records** — Retrieves data matching saved search criteria from Dynamo using advanced filter queries * **Get view sql, document schema, view** — Returns data from a specific SQL view in Dynamo using the view name * **Total entity** — Returns total count of items for a given Dynamo entity * **Id entity by** — Returns a single instance of a Dynamo entity by its ID with optional column selection and formatting controls * **Key reset api** — Removes the user’s API key from the server cache ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Echtpost MCP connector > Connect to Echtpost MCP. Send physical postcards and letters programmatically via the Echtpost API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'echtpostmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Echtpost MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'echtpostmcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "echtpostmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Echtpost MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="echtpostmcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update group, contact** — Update a contact group * **Fit preview** — Check if a message fits on a postcard with the given font settings * **List templates, motives, groups** — List available card templates for the account * **Get template, motive, me** — Get details of a specific template by ID * **Delete group, contact** — Delete a contact group * **Create group, contact, card from template** — Create a new contact group ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Eden MCP connector > Eden is an AI-powered content creation platform that discovers viral trends across 3M+ social media posts and helps creators generate content in their... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'edenmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Eden MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'edenmcp_eden_analyze_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "edenmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Eden MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="edenmcp_eden_analyze_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update eden** — Update rows in an Eden table: set cell values, rename, check/uncheck the done circle, or soft-remove * **Search eden** — Search the bundled knowledge of a marketplace-installed (managed) Custom AI — managed installs keep knowledge in a server-side bundle, so eden\_get\_custom\_ai returns an empty sources list for them * **Multipart eden scheduling media** — Drive a multipart scheduling-media upload from eden\_prepare\_scheduling\_media\_upload’s multipart plan, one step at a time * **Board eden save items to, eden trash, eden save posts to** — Place existing workspace/library items onto a board as cards * **Read eden** — Read a TABLE item (Eden’s list / database item, called ‘tables’ in the UI): its column schema plus every row with that row’s cell values * **List eden** — List the Custom AI (Eden’s rebranded Skills feature) available in an Eden workspace ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # EODHD MCP connector > EODHD (End of Day Historical Data) provides comprehensive financial market data including end-of-day stock prices, historical OHLCV data, fundamentals... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'eodhdmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize EODHD MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'eodhdmcp_get_asx_corporate_actions', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "eodhdmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize EODHD MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="eodhdmcp_get_asx_corporate_actions", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get sanctions vessels, sanctions sources, sanctions programs** — Search sanctioned vessels (e.g * **Screener stock** — Screen and filter stocks by fundamental and technical criteria * **Id retrieve description by** — Retrieve built-in EODHD API documentation by numeric type and id * **Ticker resolve** — Resolve a company name, partial ticker, or ISIN to SYMBOL.EXCHANGE format (and ISIN) * **List mp indices** — \[Marketplace] List all available S\&P and Dow Jones indices with end-of-day details * **Components mp index** — \[Marketplace] Get constituent stocks of a specific S\&P or Dow Jones index, including historical component changes for major indices ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Era Context MCP connector > Connect to Era Context MCP. Access personal finance data including transactions, accounts, spending insights, and AI-powered financial knowledge from Era. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'eracontextmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Era Context MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'eracontextmcp_nurture__get_my_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "eracontextmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Era Context MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="eracontextmcp_nurture__get_my_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Subscription nurture set, billing uncancel, billing cancel** — Subscribe the caller to, or unsubscribe them from, a nurture (lifecycle email) campaign * \*\*Get nurture , insights , referral \*\* — Get the caller’s own nurture (lifecycle email) campaign enrollment status — which campaigns they are currently enrolled in, their progress through each, and whether they have unsubscribed * **Questions knowledge reset pack** — Warning: this cannot be undone — only call when you have high confidence the user wants to reset and re-surface all previously skipped or snoozed questions * **Resync connections trigger connection** — Trigger an on-demand data resync for a bank connection * **Mode connections set proactive sync** — Record whether Era may proactively ask a bank connection’s provider for fresh data on its own schedule * \*\*List connections , billing \*\* — List every one of the user’s bank connections with an honest, provider-agnostic status for each: whether it is healthy, syncing with no data yet, needs reconnecting, is terminally denied, is currently disconnected, or one of several other narrower states ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Eraser MCP connector > Connect to Eraser MCP. Create and edit diagrams, flowcharts, and technical documentation using Eraser's AI-powered diagramming tools. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'erasermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Eraser MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'erasermcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "erasermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Eraser MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="erasermcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update template or reference, rules, preset** — Rename a template or reference file * **Team select** — Set the active team for the session when the user belongs to multiple teams (OAuth only) * **Search records** — Full-text and semantic search across files or diagrams * **Reference publish template or, add or remove template or** — Publish a new version of a template/reference file * **Create manually, template or reference** — ADVANCED — most callers should use create\_document instead * **List teams, presets, folders** — List the teams the current user belongs to (OAuth only) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Evertrace AI connector > Connect to evertrace.ai to search and manage talent signals, saved searches, and lists. Access rich professional profiles with scoring, experiences, and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'evertrace' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'evertrace_cities_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "evertrace" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="evertrace_cities_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List companies, entries delete, entries get** — Search companies by name or look up by specific IDs * **Delete lists, searches** — Permanently delete a list and all its entries * **Update lists, searches** — Rename a list * **Get lists, signals, searches** — Get a list by ID with its entries, accesses, and creator information * **Create lists, searches** — Create a new list * **Viewed signal mark** — Mark a signal as viewed by the current user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Exa connector > Connect to Exa to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, run in-depth... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Exa credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'exa' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'exa_list_webset_monitors', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "exa" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="exa_list_webset_monitors", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update webset** — Update an existing Exa Webset’s metadata or external reference ID * **List webset monitors, websets, webset items** — List Monitors, which keep a Webset continuously refreshed on a schedule via a cron cadence * **Get webset monitor, webset item, research task** — Get a single Monitor’s configuration, enabled/disabled status, cadence, and last/next run details * **Create webset search, webset monitor, webset enrichment** — Run an additional search against an existing Exa Webset to discover more matching items without creating a brand-new webset * **Enrichment cancel webset** — Cancel a running enrichment on a webset, stopping further per-item research * **Webset cancel** — Cancel a running Exa Webset so it stops discovering new items ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Exa MCP connector > Connect to Exa MCP to perform AI-powered semantic web search, crawl websites for structured content, get natural language answers from the web, and run... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Exa MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'examcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'examcp_web_fetch_exa', 19 toolInput: { urls: [] }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "examcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"urls":[]}, 19 tool_name="examcp_web_fetch_exa", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search web** — Search the web and get clean, ready-to-use content * **Fetch web** — Read one or more webpages and return their full content as clean markdown ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Excalidraw MCP connector > Excalidraw+ is a collaborative whiteboard and diagramming platform. The Excalidraw MCP server lets AI agents manage scenes, collections, workspaces... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'excalidrawmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'excalidrawmcp_get_workspace', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "excalidrawmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="excalidrawmcp_get_workspace", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update workspace user, workspace, scene** — Modify workspace-level properties for a specific user such as their name, picture, or role * **Screenshot take** — Render a scene, or a specific frame, as a PNG image so you can visually inspect the current Excalidraw content * **Search scene content** — Search a scene’s shapes and text without loading the full scene content * **User remove workspace** — Remove a user from the workspace * **Read excalidraw format** — Returns the Excalidraw element format reference with agent-facing rules for constructing valid diagram payloads * **List workspace users, scenes, logs** — Retrieve a paginated list of all members in the current workspace ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Expo MCP connector > Expo is a platform for building universal React Native apps; its MCP server exposes developer services including EAS builds, submissions, and project... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'expomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Expo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'expomcp_build_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "expomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Expo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="expomcp_build_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Validate workflow** — Validates an EAS workflow YAML file for syntax and configuration errors * **Run workflow, build** — Triggers an EAS workflow run for a project * **Logs workflow, build** — Fetches logs for a specific job in an EAS workflow run * **List workflow, build** — Lists recent EAS workflow runs for a project * **Info workflow, build** — Fetches detailed information about a specific EAS workflow run by ID including status, job results, errors, and artifacts * **Create workflow** — Creates a new EAS workflow YAML file for Expo projects or fetches workflow syntax documentation ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Fathom connector > Connect to Fathom AI meeting assistant. Record, transcribe, and summarize meetings with AI-powered insights 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Fathom credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fathom' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'fathom_list_meeting_types', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fathom" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="fathom_list_meeting_types", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Download request recording** — Request Fathom to generate a downloadable video and/or audio file for a specific recording * **List users, teams, team members** — List users in your Fathom organization along with their settings and meeting-view permissions * **Get recording download status, recording transcript, recording summary** — Check the status of a previously requested recording download in Fathom, identified by recording\_id and the download\_id returned by Request Recording Download * **Delete webhook** — Delete a webhook subscription in Fathom by its ID * **Create webhook** — Create a new webhook subscription in Fathom ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Fathom MCP connector > Connect to Fathom MCP to access AI meeting notes, summaries, transcripts, and recordings from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fathommcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Fathom MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fathommcp_get_identity', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fathommcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Fathom MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fathommcp_get_identity", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search meetings** — Search meeting summaries and titles by topic or keyword (AND logic) * **List teams, meetings** — List all Fathom teams the current user belongs to * **Get recording by url, recording by call id, meeting transcript** — Resolve a Fathom URL to a recording\_id plus title, date, and url * **Person find** — Find a person by name across meeting speakers, then return contact info and compact summaries for matched meetings ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # FellowAI MCP connector > Connect to Fellow.ai MCP to manage meeting notes, action items, agendas, and team collaboration workflows directly from your AI agent. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your FellowAI MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fellowaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize FellowAI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fellowaimcp_get_action_items', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fellowaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize FellowAI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fellowaimcp_get_action_items", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search meetings** — Search for meetings across calendar events and notes, with filters for participants, date range, content, and summary * **List channels** — List all available channels in the workspace, optionally filtered by name or type * **Get meeting transcript, meeting summary, meeting participants** — Retrieve the transcript of a meeting ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Search for recent meetings Use `fellowaimcp_search_meetings` to find meetings by title, date range, participants, or content. Set `user_has_calendar_event: true` to search only the current user’s own meetings. * Node.js ```typescript 1 const meetings = await actions.executeTool({ 2 connectionName: 'fellowaimcp', 3 identifier: 'user_123', 4 toolName: 'fellowaimcp_search_meetings', 5 toolInput: { 6 from_date: '2024-01-01', 7 to_date: '2024-01-31', 8 user_has_calendar_event: true, 9 has_summary: true, 10 }, 11 }); 12 console.log(meetings); ``` * Python ```python 1 meetings = actions.execute_tool( 2 connection_name="fellowaimcp", 3 identifier="user_123", 4 tool_name="fellowaimcp_search_meetings", 5 tool_input={ 6 "from_date": "2024-01-01", 7 "to_date": "2024-01-31", 8 "user_has_calendar_event": True, 9 "has_summary": True, 10 }, 11 ) 12 print(meetings) ``` ### Get a meeting summary Use `fellowaimcp_get_meeting_summary` to retrieve AI-generated summaries for one or more meetings, including key points, decisions, and action items. * Node.js ```typescript 1 const summary = await actions.executeTool({ 2 connectionName: 'fellowaimcp', 3 identifier: 'user_123', 4 toolName: 'fellowaimcp_get_meeting_summary', 5 toolInput: { 6 meeting_ids: ['meeting_abc123'], 7 }, 8 }); 9 console.log(summary); ``` * Python ```python 1 summary = actions.execute_tool( 2 connection_name="fellowaimcp", 3 identifier="user_123", 4 tool_name="fellowaimcp_get_meeting_summary", 5 tool_input={ 6 "meeting_ids": ["meeting_abc123"], 7 }, 8 ) 9 print(summary) ``` ### Fetch overdue action items Use `fellowaimcp_get_action_items` to retrieve action items assigned to the user, filtered by status or date range. * Node.js ```typescript 1 const actionItems = await actions.executeTool({ 2 connectionName: 'fellowaimcp', 3 identifier: 'user_123', 4 toolName: 'fellowaimcp_get_action_items', 5 toolInput: { 6 is_overdue: true, 7 }, 8 }); 9 console.log(actionItems); ``` * Python ```python 1 action_items = actions.execute_tool( 2 connection_name="fellowaimcp", 3 identifier="user_123", 4 tool_name="fellowaimcp_get_action_items", 5 tool_input={ 6 "is_overdue": True, 7 }, 8 ) 9 print(action_items) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Felt connector > Connect to Felt, a cloud-native GIS and mapping platform, to manage maps, layers, and geospatial data, query connected spatial databases, and collaborate... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'feltmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Felt:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'feltmcp_get_sql_guidance', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "feltmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Felt:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="feltmcp_get_sql_guidance", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **I who am** — Get information about the current user and workspace they are logged into * **Annotations upsert** — Create or update lightweight markup annotations on a map — pins, notes, sketched shapes and lines * **Map upload contents to, share, render** — Add Geo data to the map as a new layer by including its contents inline as raw text (no file upload) * **Update map, layer properties, layer group properties** — Update a map’s title, basemap, zoom level, or basemap label visibility * **Visibility set** — Show and/or hide layers, layer groups, and legend items (categories or class breaks) * **Interaction set layer group** — Set how a layer group’s layers are toggled in the legend ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Fever MCP connector > Fever is a live entertainment discovery platform. This MCP connector gives AI assistants direct access to Fever's global event catalog — search events by... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fevermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Fever MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fevermcp_search_events', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fevermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Fever MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fevermcp_search_events", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search events, cities** — Find events, activities, and experiences available in a specific city through Fever ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Fibery MCP connector > Connect to Fibery MCP. Query, create, and update entities across your Fibery workspace using the Fibery API and AI assistant. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fiberymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Fibery MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fiberymcp_get_connectors_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fiberymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Fibery MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fiberymcp_get_connectors_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tab, report, dimension** — Updates scalar properties of an existing tab in a Fibery report * **Text set block, replace block** — Rewrites the inline content of text blocks from markdown * **Attrs set block** — Merges attributes into blocks’ attrs (e.g * **Comment reply document, add** — Adds replies to existing inline comment threads in a document * **Tab remove, add table, add metric** — Removes a tab from an existing Fibery report * **Dimension remove** — Removes a single dimension from a tab in a Fibery report ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Figma connector > Connect to Figma to access user files, teams, projects, and design metadata via OAuth 2.0 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Figma credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'figma' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Figma:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'figma_activity_logs_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "figma" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Figma:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="figma_activity_logs_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List webhooks, team folders, folder files** — Return webhooks for a given context (team, project, or file) or for an entire plan, if they exist * **Get oembed, folder meta, file meta** — Return oEmbed data (per the oEmbed spec) for a Figma file or published Figma Make site URL — useful for generating rich embeds/previews on external pages * **Delete comment reaction, dev resource, file comment** — Removes the authenticated user’s emoji reaction from a comment in a Figma file * **Create file comment, webhook, comment reaction** — Posts a new comment on a Figma file * **Update file variables, webhook, dev resource** — Create, update, or delete variables, variable collections, and modes in a Figma file * **Render file images** — Renders nodes from a Figma file as images (PNG, JPG, SVG, or PDF) and returns URLs to download them ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Financial Datasets MCP connector > Financial Datasets provides an MCP interface to financial data APIs covering stock prices, financial statements, earnings, insider trades, and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'financialdatasetsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Financial Datasets MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'financialdatasetsmcp_get_beneficial_owners', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "financialdatasetsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Financial Datasets MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="financialdatasetsmcp_get_beneficial_owners", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get insider ownership, beneficial ownership, beneficial owners** — Retrieves insider ownership statements for a company: what officers, directors, and 10% owners actually HOLD (common shares, options, RSUs), sourced from SEC Form 3 (an insider’s initial statement of ownership) and Form 5 (the annual statement) * **Stocks screen** — Screen stocks based on financial criteria and filters to find companies matching specific metrics * **List stock screener filters, filing item types** — Lists all available filters that can be used with the stock screener tool ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Firecrawl MCP connector > Connect to Firecrawl MCP. Scrape, crawl, search, extract structured data, and monitor websites using Firecrawl's AI-powered web scraping API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Firecrawl MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'firecrawlmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'firecrawlmcp_firecrawl_monitor_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "firecrawlmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="firecrawlmcp_firecrawl_monitor_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search firecrawl research, firecrawl developer** — Search research paper metadata and abstracts across biomedical, life-science, clinical, and arXiv sources by natural-language query * **Papers firecrawl research related** — Find citation-graph related papers (similar, citing, or referenced) for one to ten seed paper IDs * **Read firecrawl research** — Retrieve in-body passages from an indexed research paper relevant to a specific question * **Paper firecrawl research inspect** — Retrieve canonical metadata (title, abstract, authors, categories, dates) for one research paper by arXiv, PMC, PMID, or DOI identifier * **Parse firecrawl** — Parse a local or uploaded document (PDF, Word, RTF, OpenDocument, spreadsheet, or HTML) into markdown, HTML, links, summary, targeted answers, or JSON matching a schema * **Feedback firecrawl** — Submit concise quality feedback (rating, issues, tags, notes) for a completed search, scrape, parse, or map job ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Scrape a page Use `firecrawlmcp_firecrawl_scrape` to extract clean markdown content from any URL. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'firecrawlmcp', 3 identifier: 'user_123', 4 toolName: 'firecrawlmcp_firecrawl_scrape', 5 toolInput: { 6 url: 'https://docs.example.com/getting-started', 7 onlyMainContent: true, 8 }, 9 }); 10 console.log(result.data); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="firecrawlmcp", 3 identifier="user_123", 4 tool_name="firecrawlmcp_firecrawl_scrape", 5 tool_input={ 6 "url": "https://docs.example.com/getting-started", 7 "onlyMainContent": True, 8 }, 9 ) 10 print(result.data) ``` ### Search the web Use `firecrawlmcp_firecrawl_search` to run a live web search and get scraped content from the top results. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'firecrawlmcp', 3 identifier: 'user_123', 4 toolName: 'firecrawlmcp_firecrawl_search', 5 toolInput: { 6 query: 'best practices for API rate limiting 2026', 7 limit: 5, 8 }, 9 }); 10 console.log(result.data); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="firecrawlmcp", 3 identifier="user_123", 4 tool_name="firecrawlmcp_firecrawl_search", 5 tool_input={ 6 "query": "best practices for API rate limiting 2026", 7 "limit": 5, 8 }, 9 ) 10 print(result.data) ``` ### Extract structured data from a URL Use `firecrawlmcp_firecrawl_extract` with a natural-language prompt and optional JSON Schema to pull structured data from one or more pages. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'firecrawlmcp', 3 identifier: 'user_123', 4 toolName: 'firecrawlmcp_firecrawl_extract', 5 toolInput: { 6 urls: ['https://example.com/pricing'], 7 prompt: 'Extract all pricing plan names and their monthly costs.', 8 }, 9 }); 10 console.log(result.data); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="firecrawlmcp", 3 identifier="user_123", 4 tool_name="firecrawlmcp_firecrawl_extract", 5 tool_input={ 6 "urls": ["https://example.com/pricing"], 7 "prompt": "Extract all pricing plan names and their monthly costs.", 8 }, 9 ) 10 print(result.data) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Fireflies MCP connector > Connect to Fireflies MCP. Search meeting transcripts, fetch recordings, manage channels, create soundbites, and retrieve analytics from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'firefliesmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Fireflies MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'firefliesmcp_fireflies_fetch', 25 toolInput: { id: 'YOUR_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "firefliesmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Fireflies MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"YOUR_ID"}, 27 tool_name="firefliesmcp_fireflies_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get fireflies** — Query multiple meeting transcripts using filter properties (date range, keyword, organizer/participant email, channel, etc) * **Update fireflies** — Rename a meeting transcript by its ID * **Meeting fireflies share, fireflies move** — Share a meeting transcript with one or more email addresses * **Search fireflies** — Search meeting transcripts using keywords or Fireflies mini-grammar syntax * **Access fireflies revoke meeting** — Revoke a previously shared meeting access for a specific email address * **List fireflies** — List all channels (folders) available to the authenticated user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # FiscalAI MCP connector > Connect to FiscalAI MCP. Access financial data for public companies including SEC filings, earnings, stock prices, financial ratios, and company profiles. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fiscalaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize FiscalAI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fiscalaimcp_api_docs', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fiscalaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize FiscalAI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fiscalaimcp_api_docs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Execute code** — Execute JavaScript code in a secure sandbox to call Fiscal.ai API functions via the codemode namespace and return results via console.log * **Docs api** — Retrieve Fiscal.ai API documentation with TypeScript type definitions for all available functions ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Flux MCP connector > Flux by Black Forest Labs provides state-of-the-art AI image generation via the FLUX.1 family of models. Generate high-quality images from text prompts... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fluxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Flux MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fluxmcp_get_credits', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fluxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Flux MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fluxmcp_get_credits", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Video generate, enhance** — Generate videos with FLUX.3 * **Vto records** — Virtual try-on: dress `person` in `garment` * **Url request upload, refresh image** — Issue a signed PUT URL for a direct image upload to BFL’s Storage bucket * **Get result, history, credits** — DO NOT CALL FROM THE LLM * **Variations generate** — Generate N more images “in the same direction” as a previously completed generation * **Image generate** — Submit one or more FLUX.2 image generations ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Folk MCP connector > Folk is a collaborative CRM that helps teams manage contacts, track relationships, and run outreach — all in one workspace. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'folkmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Folk MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'folkmcp_folk_create_person', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "folkmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Folk MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="folkmcp_folk_create_person", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update folk** — Update an existing person (contact) record in Folk CRM with new native or custom field values * **Search folk** — Search for people (contacts) in the Folk CRM workspace by name, email, or custom field values * **Get folk** — Retrieves the complete structure of the folk workspace: groups, entity types per group, native fields, custom field definitions, pipeline views, and workspace members * **Create folk** — Create a new person (contact) record in the Folk CRM workspace with native and custom field values ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Freshdesk connector > Connect to Freshdesk. Manage tickets, contacts, companies, and customer support workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create time entry, ticket note, solution article** — Log a time entry against a ticket for billing or effort tracking * **List time entries, solution articles, satisfaction ratings** — Retrieve time entries logged across tickets, with filtering by agent, company, and execution date range * **Filter tickets** — Search tickets using Freshdesk’s structured query syntax (field:value expressions combined with AND/OR), for filtering beyond what List Tickets’ predefined filters support * **Forward ticket** — Forward a ticket’s conversation to one or more external email addresses, optionally including the full ticket thread * **Delete ticket, contact, company** — Move a ticket to the trash in Freshdesk * **Update contact, company, agent** — Update an existing contact in Freshdesk ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Front connector > Connect to Front to manage conversations, messages, comments, drafts, contacts, tags, inboxes, teammates, and channels. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'front' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Front:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'front_list_accounts', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "front" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Front:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="front_list_accounts", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update teammate, tag, conversation assignee** — Update a teammate’s username, name, or availability status in Front * **Send message** — Send a new outbound message from a Front channel * **Search conversations** — Search for conversations * **Conversation reply to** — Reply to a conversation by sending a message and appending it to the conversation * **Tag remove conversation, add conversation** — Remove one or more tags from a conversation * **Message receive, import** — Receive a custom message in Front ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Front MCP connector > Connect to Front via MCP to manage conversations, comments, drafts, contacts, tags, inboxes, and teammates directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'frontmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Front MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'frontmcp_get_my_identity', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "frontmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Front MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="frontmcp_get_my_identity", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update draft, conversation status** — Update the body, subject, or recipients of an existing draft * **Conversation tag, move, assign** — Add or remove tags on a conversation * **Send message** — Send a draft message created via create\_draft (queues it for delivery) * **Search conversations, contacts, accounts** — Search conversations by query and/or filters * **Read message, conversation, contact** — Fetch a single message by ID with full content * **List teams, teammates, tags** — List teams in the workspace ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Fullenrich MCP connector > Connect to FullEnrich MCP. Enrich contacts with verified email addresses and phone numbers using waterfall enrichment across multiple data providers. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'fullenrichmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Fullenrich MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'fullenrichmcp_get_credits', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "fullenrichmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Fullenrich MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="fullenrichmcp_get_credits", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List seniorities, functions subfunctions, industries** — List all valid seniority level values that can be used as filter inputs in search\_people and export\_contacts (current\_position\_seniority\_level) * **Search people, contact by email, companies** — Search for contacts in the FullEnrich database using filters such as name, company, job title, location, and skills * **Get enrichment results, credits** — Get the current status and up to 10 result rows from an enrichment job by enrichment ID * **Results export enrichment** — Export all results from a completed enrichment job to a CSV or JSON file * **Contacts export** — Export contact search results to a CSV or JSON file * **Companies export** — Export company search results to a CSV or JSON file ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Gainsight connector > Connect to Gainsight Customer Success to manage companies, contacts, calls to action, success plans, timeline activities, and custom objects. Power... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Gainsight credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gainsight' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'gainsight_company_query', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gainsight" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="gainsight_company_query", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update task, object, goal** — Update one or more fields on an existing task in Gainsight Cockpit * **List playbook, task, success plan** — List Playbooks configured in Gainsight Cockpit, optionally filtered by entity type, active status, and playbook type * **Delete object** — Delete a single record from any standard or custom Gainsight MDA object by its GSID * **Create object, goal, company** — Insert up to 50 records into any standard or custom Gainsight MDA object by name * **Fetch goal** — Fetches/queries Customer Goal records in Gainsight * **Query timeline, scorecard, relationships** — Search and filter Gainsight Timeline activity records by any field ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Github connector > GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Github credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'github' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Github:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'github_gists_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "github" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Github:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="github_gists_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read repositories** — fetch repo metadata, files, commits, branches, and tags * **Manage issues** — create, update, close, and comment on issues * **Work with pull requests** — open PRs, post reviews, and merge changes * **Search code** — search across repositories by keyword, language, or file path * **Trigger workflows** — dispatch GitHub Actions workflow runs ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # GitHub MCP connector > Connect to GitHub MCP. Manage repositories, issues, pull requests, branches, and files directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your GitHub MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'githubmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize GitHub MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'githubmcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "githubmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize GitHub MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="githubmcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search commits, users, repositories** — Search for GitHub commits by commit message and other metadata * **List issue fields, tags, repository collaborators** — List custom issue fields available for a GitHub repository or organization * **Update pull request branch, pull request** — Update a pull request branch with the latest changes from the base branch * **Write sub issue, pull request review, issue** — Add, remove, or reorder a sub-issue under a parent issue in a GitHub repository * **Run secret scanning** — Scan files or content for exposed secrets such as API keys, passwords, and tokens * **Review request copilot, add comment to pending** — Request a GitHub Copilot automated code review for a pull request ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # GitHub (Personal Access Token) connector > GitHub is a cloud-based Git repository hosting service that allows developers to store, manage, and track changes to their code. This variant... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'githubpat' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'githubpat_gists_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "githubpat" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="githubpat_gists_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get workflow, webhook, team membership** — Get a single workflow by its ID or filename * **Enable workflow** — Enable a workflow that was previously disabled * **Disable workflow** — Disable a workflow, preventing it from running until re-enabled * **List webhooks, sub issues, secret scanning alerts** — List webhooks configured on a repository * **Update webhook, team, repo variable** — Update the configuration, events, or active state of an existing repository webhook * **Ping webhook** — Trigger a ping event to test that a repository webhook is configured correctly ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # GitLab connector > Connect to GitLab to manage repositories, issues, merge requests, pipelines, CI/CD, users, groups, and DevOps workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your GitLab credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gitlab' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize GitLab:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gitlab_current_user_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gitlab" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize GitLab:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gitlab_current_user_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List wiki pages, todos, snippets** — Lists all wiki pages for a project * **Update wiki page, user, snippet** — Updates the title, content, or format of an existing wiki page * **Get wiki page, user status, snippet** — Retrieves a specific wiki page for a project by its slug * **Delete wiki page, user, snippet** — Deletes a wiki page from a project * **Create wiki page, user, snippet** — Creates a new wiki page for a project * **Unblock user** — Unblocks a previously-blocked user account, restoring their ability to sign in ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Globalping MCP connector > Globalping is a global network measurement platform for running ping, traceroute, DNS lookup, HTTP, and MTR tests from hundreds of probe locations... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'globalpingmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Globalping MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'globalpingmcp_get_more_tools', 25 toolInput: { context: 'YOUR_CONTEXT' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "globalpingmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Globalping MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"context":"YOUR_CONTEXT"}, 27 tool_name="globalpingmcp_get_more_tools", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Traceroute records** — Trace the network path to a target (domain or IP) from global locations * **Ping records** — Measure network latency, packet loss, and reachability to a target (domain or IP) from globally distributed probes * **Mtr records** — Run an MTR (My Traceroute) diagnostic, which combines Ping and Traceroute * **Locations records** — Retrieve the list of available Globalping probe locations * **Limits records** — Check current API rate limits and remaining credits for the Globalping account * **Http records** — Send HTTP/HTTPS requests (GET, HEAD, or OPTIONS) to a URL from global locations ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Gmail connector > Gmail is Google's cloud based email service that allows you to access your messages from any computer or device with just a web browser. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Gmail credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gmail' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Gmail:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gmail_fetch_mails', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gmail" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Gmail:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gmail_fetch_mails", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read emails** — fetch messages, threads, and attachments from any label or inbox * **Send and reply** — compose new emails and reply to existing threads on behalf of your users * **Search messages** — query Gmail with full search syntax to find emails by sender, subject, or content * **Manage labels** — apply, remove, and list labels to organize messages * **Access contacts** — look up contacts and people from the user’s address book ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # GoCardless MCP connector > Connect to GoCardless MCP. Retrieve and list customers, mandates, payments, payouts, refunds, and subscriptions, and explore integration options from your... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gocardlessmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize GoCardless MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gocardlessmcp_get_environment', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gocardlessmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize GoCardless MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gocardlessmcp_get_environment", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create subscription, refund, payment template link** — Create a recurring subscription against a mandate, scheduling regular payments on a weekly, monthly, or yearly interval * **Payment cancel** — Cancel a payment before it is submitted to the bank * **Mandate cancel** — Cancel a mandate (Direct Debit authorisation) * **Feedback submit** — Submit a helpfulness rating (1–5) for the current MCP session, with an optional comment * **Read gocardless resource** — Read the contents of a GoCardless resource by URI to fetch API endpoint details or documentation * **List subscriptions, refunds, payouts** — List subscriptions (recurring payment schedules), optionally filtered by status, customer, or mandate ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Gong connector > Connect with Gong to sync calls, transcripts, insights, coaching and CRM activity 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Gong credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gong' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Gong:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gong_call_outcomes_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gong" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Gong:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gong_call_outcomes_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get user settings history, user, calls ai content** — Retrieve the history of settings changes for a single Gong user, such as changes to their role, team, or permission profile over time * **Day stats activity** — Retrieve day-by-day activity statistics for one or more Gong users across a date range, with one record per user per day that had activity * **Period stats activity aggregate by** — Retrieve aggregated activity statistics for one or more Gong users, grouped into calendar time periods (e.g * **Aggregate stats activity** — Retrieve aggregated activity statistics (calls, emails, meetings and similar counts) for one or more Gong users over a date range, with one summary record returned per user with any activity in the range * **Status meetings integration, engage prospects bulk assign** — Check whether Gong’s meeting recording integration is properly set up for a list of users, by email * **Delete meeting** — Delete a scheduled Gong meeting by its meeting ID, so Gong no longer joins or records it ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Gong MCP connector > Connect with Gong MCP to access calls, transcripts, insights, coaching, and sales engagement data via the Model Context Protocol 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Gong MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gongmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Gong MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gongmcp_ask_account', 25 toolInput: { crmAccount: 'YOUR_CRMACCOUNT', question: 'YOUR_QUESTION' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gongmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Gong MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"crmAccount":"YOUR_CRMACCOUNT","question":"YOUR_QUESTION"}, 27 tool_name="gongmcp_ask_account", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Brief generate** — Create a comprehensive structured brief about a CRM entity (account, deal, or contact) by analyzing Gong activities within a specified time period * **Deal ask** — Answer natural-language questions about a specific CRM deal or opportunity by analyzing Gong activities (calls and messages) within a defined time range * **Account ask** — Answer natural-language questions about a specific CRM account by analyzing Gong activities (calls and messages) within a defined time range ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Ads connector > Connect to Google Ads to manage advertising campaigns, analyze performance metrics, and optimize ad spending across Google's advertising platform 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Ads credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googleads' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Ads:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googleads_customers_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googleads" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Ads:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googleads_customers_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List customer, user** — Add or remove members of a Customer Match user list by uploading already-hashed contact details * **Link campaign asset, ad group asset** — Attach an existing asset to a campaign so it can serve with that campaign, for example a sitelink, callout, structured snippet or image * **Modifier ad group bid** — Create, update or remove an ad-group-level bid adjustment, so bids are raised or lowered for a segment such as a device type * **Suggest geo target constant** — Look up Google Ads geo target constant resource names for location names (cities, regions, countries) or geo-target IDs * **Search responsive** — Execute a GAQL (Google Ads Query Language) query to retrieve campaigns, ad groups, keywords, metrics, and any other Google Ads data * **Create label, keyword, conversion action** — Create a label that can be applied to campaigns, ad groups, ads, or keywords for organization and filtering ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Analytics connector > Connect to Google Analytics (GA4) to run reports, realtime reports, and pivot reports, check dimension/metric compatibility, and manage audience exports... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Analytics credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googleanalytics' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Analytics:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googleanalytics_list_account_summaries', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googleanalytics" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Analytics:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googleanalytics_list_account_summaries", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update property, measurement protocol secret, key event** — Update an existing Google Analytics property’s editable fields (display name, industry category, time zone, currency code) * **Search change history events** — Search the configuration change history for a Google Analytics account or its child properties (e.g * **Run report, realtime report, pivot report** — Run a Google Analytics 4 (GA4) report: returns a customized table of event data for a property, broken down by the requested dimensions and metrics over a date range * **Query audience export** — Retrieve the rows (users and their dimension values) from a GA4 audience export that is in the ACTIVE state * **Ticket provision account** — Request a ticket for creating a new Google Analytics account * **List properties, measurement protocol secrets, key events** — List Google Analytics properties matching a filter, such as those belonging to a parent account/property or linked to a Firebase project ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Business Profile connector > Google Business Profile lets businesses manage their presence across Google Search and Maps — business information, locations, performance/insights... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Business Profile credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlebusinessprofile' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Business Profile:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlebusinessprofile_list_accounts', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlebusinessprofile" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Business Profile:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlebusinessprofile_list_accounts", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Answer upsert** — Create or replace the caller’s answer to a customer question on a Google Business Profile location, using the legacy My Business API v4 * **Update question, notification settings, account admin** — Update the text of an existing customer question on a Google Business Profile location using the legacy My Business API v4 * **Search google locations, keywords, chains** — Search Google’s existing Maps location data by free-text query (business name and address) before creating or claiming a new location * **Insights report local post** — Get view and call-to-action click metrics for up to 100 local posts (What’s New updates) on a single location, in one call, using the legacy My Business API v4 * **List questions, location verifications, invitations** — List the customer questions posted on a Google Business Profile location using the legacy My Business API v4 * **Get voice of merchant state, location google updated, chain** — Check whether a Google Business Profile location has ‘Voice of Merchant’ — meaning it is verified, not suspended, and eligible to have its edits reflected on Google Search and Maps ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Calendar connector > Google Calendar is Google's cloud-based calendar service that allows you to manage your events, appointments, and schedules from any computer or device... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Calendar credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlecalendar' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Calendar:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlecalendar_get_colors', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlecalendar" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Calendar:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlecalendar_get_colors", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update calendar list entry, acl rule, calendar** — Update the authenticated user’s personal display settings for a calendar in their calendar list, such as its color, visibility, or whether it’s shown * **Ownership transfer calendar** — Transfer ownership of a secondary calendar to another user within a Google Workspace organization * **List remove calendar from, settings, add calendar to** — Unsubscribe the authenticated user from a calendar by removing it from their calendar list * **Event import, quick add, move** — Import a private copy of an existing event, identified by its iCalUID, into a calendar in a connected Google Calendar account * **Get setting, colors, calendar list entry** — Retrieve a single user preference setting from a connected Google Calendar account, such as the user’s timezone or week start day * **Calendar clear** — Permanently delete all events on the authenticated user’s primary Google Calendar ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Chat connector > Google Chat is Google's messaging and collaboration platform that lets you create and manage spaces, send and search messages, react with emoji, and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlechat' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Chat:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlechat_find_group_chats', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlechat" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Chat:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlechat_find_group_chats", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Media upload, download** — Upload a file (up to 200MB) as a Google Chat attachment, to be referenced when sending a message * **Update user availability, space read state, space notification setting** — Update the authenticated user’s custom status message in Google Chat, with an optional emoji and expiration * **Space setup, find direct message** — Create a Google Chat space and add specified members to it in a single call * **Search spaces, messages** — Search for spaces across a Google Workspace organization using domain-wide admin access * **Section reposition** — Change the sort order of a section in Google Chat’s navigation panel, moving it to an absolute position or to the start or end of the section list * **Message replace** — Update an existing Google Chat message using the PUT-based update endpoint ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Classroom connector > Google Classroom is Google's free web-based platform for schools that streamlines creating, distributing, and grading assignments, and simplifies... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googleclassroom' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Classroom:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googleclassroom_courses_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googleclassroom" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Classroom:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googleclassroom_courses_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get user profile, topic, teacher** — Retrieve a single user’s Google Classroom profile by numeric ID, email address, or ‘me’ * **List topics, teachers, students** — List the topics in a Google Classroom course that the requester is permitted to view * **Patch topic, student submission, student group** — Update the name of an existing Google Classroom topic * **Delete topic, teacher, student group member** — Permanently delete a topic from a Google Classroom course * **Create topic, teacher, student group member** — Create a new topic (organizational label) in a Google Classroom course * **In student submission turn** — Turn in a student submission for grading, as the student who owns it ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Cloud Vision connector > Google Cloud Vision API lets you derive insights from images using pre-trained machine learning models — label detection, OCR/text extraction, face and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlecloudvision' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Cloud Vision:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlecloudvision_operations_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlecloudvision" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Cloud Vision:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlecloudvision_operations_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List reference image, product set products, product set** — List the reference images attached to a Product Search product * **Get reference image, product set, product** — Get a single reference image by its full resource name * **Delete reference image, product set, product** — Permanently delete a reference image from a Product Search product; this removes only the Vision API’s reference to the image and does not delete the underlying image file in Google Cloud Storage * **Create reference image, product set, product** — Add a reference image to a Product Search product by pointing at an image file already stored in Google Cloud Storage * **Update product, product set** — Update a product’s display name, description, and/or labels in Google Cloud Vision Product Search via a partial update (PATCH) * **Product set remove product, set add product** — Remove a product from a Google Cloud Vision product set, detaching it from that set’s similarity-search scope ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Contacts connector > Google Contacts (People API) lets you manage your contacts, contact groups, and directory information. Create, read, update, and delete contacts and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Contacts credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlecontacts' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Contacts:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlecontacts_groups_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlecontacts" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Contacts:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlecontacts_groups_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get people batch, groups batch, group** — Retrieves up to 200 contacts in a single request by their resource names from Google Contacts * **Search other contacts, directory, contacts** — Searches the authenticated user’s ‘Other Contacts’ by prefix query across names, email addresses, and phone numbers * **List other contacts, groups, directory** — Returns the authenticated user’s ‘Other Contacts’ — contacts auto-generated from email history that haven’t been saved to personal contacts * **Copy other contact** — Copies an ‘Other Contact’ (auto-generated from email history) into the authenticated user’s main contacts (myContacts group) * **Update group, contacts batch, contact** — Updates the name of an existing contact group in Google Contacts * **Modify group members** — Adds or removes contacts from a contact group ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Docs connector > Connect to Google Docs. Create, edit, and collaborate on documents 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Docs credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googledocs' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Docs:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googledocs_list_documents', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googledocs" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Docs:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googledocs_list_documents", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update table row style, table column properties, table cell style** — Set a table row’s minimum height, mark it as a header-style row, or prevent it from splitting across pages * **Cells unmerge table, merge table** — Unmerge a previously merged rectangular range of cells in an existing Google Doc table, splitting it back into individual cells * **Content replace named range** — Replace the content of a named range (or every range sharing a name) in a Google Doc with new text * **Image replace, insert inline** — Replace an existing image in a Google Doc with a new image fetched from a publicly accessible URL, keeping the same position and size * **Suggestion reject, accept** — Reject a single tracked-change suggestion in a Google Doc by its suggestion ID, discarding the suggested edit * **Rows pin table header** — Pin a number of leading rows in a Google Doc table so they repeat as a header when the table spans multiple pages ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Drive connector > Connect to Google Drive. Manage files, folders, and sharing permissions 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Drive credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googledrive' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Drive:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googledrive_get_about', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googledrive" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Drive:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googledrive_get_about", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update shared drive, reply, revision** — Rename a Google Drive shared drive, or update its restrictions on who can share, copy, print, or download items within it * **Drive unhide shared, hide shared** — Restore a previously hidden shared drive to the default view for the current user * **Proposal resolve access** — Approve or deny a pending access proposal on a Google Drive file, optionally granting a specific role and notifying the requester by email * **List changes, access proposals, shared drives** — List changes (files created, modified, moved, deleted, or shared) since a given page token, for efficiently keeping an external system in sync with Google Drive without re-scanning everything * **Get start page token, shared drive, reply** — Get the starting page token to use with List Changes when beginning a new sync of a Google Drive (or a specific shared drive) * **Delete shared drive, reply, revision** — Permanently delete a Google Drive shared drive ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Workspace (DWD) connector > Connect to Google Workspace APIs (Gmail, Drive, Docs, Sheets, Slides, Forms) using a GCP service account with Domain-Wide Delegation for server-to-server... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Workspace (DWD) credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read and search emails** — fetch messages, threads, and attachments from any Gmail label or inbox * **Send and manage emails** — compose messages, manage drafts, and modify labels on Gmail messages * **Manage Google Drive files** — share, move, copy, and query activity on files and folders in Google Drive * **Access Google Calendar** — read, create, and manage calendar events across a user’s calendars * **Manage Google Vault** — list matters and manage legal holds in Google Vault * **Administer user settings** — update vacation auto-reply settings and other Gmail account configurations ## Authentication [Section titled “Authentication”](#authentication) This connector uses **Service Account with Domain-Wide Delegation (DWD)**. You create a GCP service account, grant it domain-wide delegation in Google Admin, and provide Scalekit with the service account JSON key. Scalekit then impersonates any user in your Google Workspace domain on demand — no per-user OAuth redirects required. ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Create a connected account [Section titled “Create a connected account”](#create-a-connected-account) Before executing tools, create a connected account for each Google Workspace user you want to impersonate. Pass the user’s email as `subject` — this tells Scalekit which Workspace user the service account should act as. The `identifier` is your application’s ID for that user. * Python ```python 1 response = scalekit_client.actions.create_connected_account( 2 # connection_name: the name of the connection you created in the setup step above 3 connection_name='googledwd', 4 identifier='user_123', 5 authorization_details={ 6 "google_dwd": { 7 # subject: the Google Workspace user you want to impersonate 8 "subject": "alice@yourcompany.com", 9 } 10 }, 11 ) 12 print(response.connected_account.id) 13 print(response.connected_account.status) ``` ## Execute tools [Section titled “Execute tools”](#execute-tools) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Forms connector > Connect to Google Forms. Create, view, and manage forms and responses securely 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Forms credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googleforms' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Forms:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googleforms_get_form', 25 toolInput: { form_id: 'YOUR_FORM_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googleforms" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Forms:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"form_id":"YOUR_FORM_ID"}, 27 tool_name="googleforms_get_form", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Settings set publish** — Update a Google Form’s publish settings: whether the form is published and whether it is currently accepting responses * **Watch renew** — Renew an existing watch on a Google Form for another seven days from now * **List watches, responses** — List the watches configured on a Google Form * **Delete watch** — Delete a watch from a Google Form, immediately stopping Pub/Sub notifications for that event type * **Create watch, form** — Create a watch on a Google Form that publishes a Cloud Pub/Sub notification when the form’s schema changes or a new response is submitted * **Update batch** — Apply a batch of update requests to a Google Form in a single atomic call ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Looker connector > Connect to Google Looker or self-hosted Looker Core. Browse dashboards, run Looks, query LookML models, and access BI data programmatically. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Looker credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlelooker' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Looker:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlelooker_get_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlelooker" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Looker:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlelooker_get_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update look, folder, dashboard** — Update one or more fields on an existing Look by ID: retitle it, move it to a different folder, point it at a different saved query, or soft-delete/restore it via the deleted flag * **Search looks, dashboards** — Search Looks by title or folder instead of listing every Look in the instance * **Run scheduled plan once, query, look** — Immediately run an existing, already-saved Scheduled Plan one time and deliver it to its configured destinations, without waiting for its next scheduled occurrence and without changing that schedule * **List scheduled plans, models, looks** — List Scheduled Plans * **Get scheduled plan, query, look** — Retrieve a single Scheduled Plan by ID: its schedule (crontab/datagroup), destinations, and the dashboard, Look, LookML dashboard, or query it delivers * **Delete scheduled plan, look, folder** — Permanently delete a Scheduled Plan by ID, stopping all future scheduled deliveries ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Meet connector > Connect to Google Meet. Create and manage video meetings with powerful collaboration features 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Meet credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlemeet' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Meet:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlemeet_list_conference_records', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlemeet" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Meet:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlemeet_list_conference_records", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update meet space** — Update the configuration of a Google Meet meeting space, such as its access type or entry point access * **List transcripts, transcript entries, smart notes** — List the transcripts generated during a Google Meet conference, given the conference record’s resource name * **Get transcript, smart note, recording** — Retrieve details of a single Google Meet transcript by its resource name, including its Google Docs export location * **Conference end meet** — End the active conference in a Google Meet space, disconnecting all participants * **Create meet space** — Create a new Google Meet meeting space ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Photos connector > Google Photos is Google's photo and video storage service for uploading, organizing into albums, and managing media created by your app. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlephotos' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Photos:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlephotos_list_albums', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlephotos" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Photos:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlephotos_list_albums", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update media item, album** — Update the description of a media item this app created or uploaded — the only field the Google Photos API allows changing on a media item * **Search media items** — Search this app’s media items by album, date range, content category, media type, or favorite status — Google removed access to a user’s full pre-existing Photos library in March 2025, so results are limited to media this app itself created or uploaded * **List picker media items, media items, albums** — Retrieve the photos and videos the user picked during a Google Photos Picker session (from create\_picker\_session) * **Get picker session, media item, album** — Check the status of a Google Photos Picker session created by create\_picker\_session * **Delete picker session** — Delete a Google Photos Picker session, e.g * **Create picker session, album, batch** — Start a new Google Photos Picker session, which lets the connected user pick any photos or videos from their FULL Google Photos library (unlike the other tools in this connector, which are restricted to app-created content only) and hand just those items to this app ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Search Console connector > Google Search Console (the Search Console API, formerly Webmaster Tools API) lets you monitor and manage a site's presence in Google Search results —... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Search Console credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlesearchconsole' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Search Console:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlesearchconsole_list_sites', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlesearchconsole" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Search Console:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googlesearchconsole_list_sites", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sitemap submit** — Submits a sitemap for a site so Google will fetch and process it * **Query search analytics** — Queries Google Search performance data (clicks, impressions, CTR, position) for a site, filtered and grouped by the dimensions you define * **List sites, sitemaps** — Lists the user’s Search Console sites (properties) along with the caller’s permission level for each — SITE\_OWNER, SITE\_FULL\_USER, SITE\_RESTRICTED\_USER, or SITE\_UNVERIFIED\_USER * **Url inspect** — Runs a Google index inspection for a single URL and reports its Google Search index status — whether and when it was last crawled and indexed, the canonical URL Google selected, mobile-usability/rich-result summary info, and any indexing issues * **Get sitemap, site** — Retrieves information about one specific sitemap submitted for a site — its type, whether it is a sitemap index, processing status (pending/downloaded), and error/warning counts * **Delete sitemap, site** — Removes a sitemap from the Sitemaps report for a site ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Sheets connector > Connect to Google Sheets. Create, edit, and analyze spreadsheets with powerful data management capabilities 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Sheets credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googlesheets' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Sheets:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googlesheets_read_spreadsheet', 25 toolInput: { spreadsheet_id: 'YOUR_SPREADSHEET_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googlesheets" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Sheets:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"spreadsheet_id":"YOUR_SPREADSHEET_ID"}, 27 tool_name="googlesheets_read_spreadsheet", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update spreadsheet properties, dimension properties, batch** — Update spreadsheet-level properties of a Google Sheet, such as its title, locale, or time zone * **Whitespace trim** — Remove leading and trailing whitespace, and collapse internal whitespace to single spaces, for every cell in a range of a Google Sheet * **Columns text to** — Split the text in a single column of a Google Sheet into multiple columns, using a delimiter such as comma, semicolon, or a custom character * **Range sort, insert, add protected** — Sort the rows within a range in a Google Sheet by a single column, ascending or descending * **Filter set basic, clear basic, batch clear values by data** — Create the standard ‘basic filter’ on a range in a Google Sheet, enabling the filter dropdown arrows in the header row * **Search developer metadata** — Search for developer metadata entries in a Google Sheet by key, or by the sheet/row/column they are attached to ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Slides connector > Connect to Google Slides to create, read, and modify presentations programmatically. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Slides credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googleslides' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Slides:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googleslides_read_presentation', 25 toolInput: { presentation_id: 'YOUR_PRESENTATION_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googleslides" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Slides:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"presentation_id":"YOUR_PRESENTATION_ID"}, 27 tool_name="googleslides_read_presentation", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get page thumbnail, page** — Generate and retrieve a thumbnail image URL for a single page (slide) in a Google Slides presentation * **Update batch** — Apply a batch of update requests to a Google Slides presentation in a single atomic call, such as inserting a slide, inserting text into a shape, creating a table, replacing text, or deleting an object * **Read presentation** — Read the complete structure and content of a Google Slides presentation including slides, text, images, shapes, and metadata * **Create presentation** — Create a new Google Slides presentation with an optional title ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Google Tasks connector > Google Tasks is Google's task management service for creating and organizing to-do items and task lists, synced across Gmail, Calendar, and mobile devices. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Google Tasks credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'googletasks' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Google Tasks:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'googletasks_list_tasklists', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "googletasks" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Google Tasks:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="googletasks_list_tasklists", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tasklist, task** — Update the title of an existing task list in a connected Google Tasks account * **Task move** — Move a task to another position in a connected Google Tasks account: reorder it among siblings, nest it under a new parent, move it to the top level, or move it to a different task list * **List tasks, tasklists** — List tasks in a task list from a connected Google Tasks account, with filters for completion, due date, and visibility of hidden/deleted items * **Get tasklist, task** — Get the details of a single task list by ID from a connected Google Tasks account * **Delete tasklist, task** — Delete a task list and all tasks it contains from a connected Google Tasks account * **Create tasklist, task** — Create a new task list for the authenticated user in a connected Google Tasks account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Gorgias MCP connector > Customer support helpdesk for e-commerce brands. Centralizes conversations from email, chat, social media, and SMS with ticket management and automation. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gorgiasmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Gorgias MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gorgiasmcp_get_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gorgiasmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Gorgias MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gorgiasmcp_get_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tone of voice, ticket, support action** — Update AI Agent tone-of-voice settings for a store * **Article unpublish help center, publish help center** — Hide an article from the storefront without deleting it * **Macro unarchive, archive, apply** — Restore a previously archived macro * **Ticket snooze, escalate** — Snooze a ticket until a given datetime, optionally leaving an internal note explaining the reason * **Search tickets** — Full-text search across ticket subjects, messages, and customer fields * **Close reply and** — Post a customer-facing reply and close the ticket in one call ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Grain connector > Grain's REST API for managing meeting recordings, transcripts, webhooks, and workspace data. Search and retrieve recordings and transcripts, upload and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'grain' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'grain_hooks_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "grain" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="grain_hooks_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List users, teams, recordings** — List the users in the Grain workspace, with their id, name, and email * **Create recording upload url, hook** — Generate a one-time upload URL for adding a new recording to Grain * **Update recording** — Update a Grain recording’s title * **User recording unshare, recording share** — Revoke a workspace user’s shared access to a Grain recording * **Team recording unshare, recording share** — Revoke a team’s shared access to a Grain recording * **Get recording transcript text, recording transcript, recording** — Get a Grain recording’s transcript as plain text, WebVTT, or SRT — ready to display or feed into subtitle/captioning tools, instead of the structured JSON segments returned by grain\_recording\_transcript\_get ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Grain MCP connector > Grain is a meeting recording and intelligence platform. Use this connector to search and retrieve meeting recordings, transcripts, notes, action items... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Grain MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'grainmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Grain MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'grainmcp_list_all_deals', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "grainmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Grain MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="grainmcp_list_all_deals", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update my settings, collection share state, project share state** — Update your personal settings * **Myself records** — Get information about the logged-in Grain user * **Team my** — Get the settings of the team you belong to * **Settings my** — Get your personal settings * **List smart topics, collections, workspace users** — Lists the smart topics configured in your Grain workspace * **Get dossier for company** — Fetches the Company Intelligence dossier for a single company by `company_id` (the id returned by `search_companies`) ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Search meeting transcripts Use `grainmcp_search_in_transcripts` to find relevant segments across all meeting recordings using hybrid semantic and keyword search. * Node.js ```typescript 1 const segments = await actions.executeTool({ 2 connectionName: 'grainmcp', 3 identifier: 'user_123', 4 toolName: 'grainmcp_search_in_transcripts', 5 toolInput: { 6 search_queries: ['pricing objection', 'competitor mention'], 7 limit: 10, 8 }, 9 }); 10 console.log(segments); ``` * Python ```python 1 segments = actions.execute_tool( 2 connection_name="grainmcp", 3 identifier="user_123", 4 tool_name="grainmcp_search_in_transcripts", 5 tool_input={ 6 "search_queries": ["pricing objection", "competitor mention"], 7 "limit": 10, 8 }, 9 ) 10 print(segments) ``` ### Fetch meeting notes and action items Use `grainmcp_fetch_meeting_notes` and `grainmcp_fetch_meeting_action_items` to retrieve AI-generated notes and extracted action items for a specific meeting. * Node.js ```typescript 1 // Fetch AI notes 2 const notes = await actions.executeTool({ 3 connectionName: 'grainmcp', 4 identifier: 'user_123', 5 toolName: 'grainmcp_fetch_meeting_notes', 6 toolInput: { meeting_id: 'meeting_abc123' }, 7 }); 8 9 // Fetch action items 10 const actions_result = await actions.executeTool({ 11 connectionName: 'grainmcp', 12 identifier: 'user_123', 13 toolName: 'grainmcp_fetch_meeting_action_items', 14 toolInput: { meeting_id: 'meeting_abc123' }, 15 }); 16 console.log(notes, actions_result); ``` * Python ```python 1 # Fetch AI notes 2 notes = actions.execute_tool( 3 connection_name="grainmcp", 4 identifier="user_123", 5 tool_name="grainmcp_fetch_meeting_notes", 6 tool_input={"meeting_id": "meeting_abc123"}, 7 ) 8 9 # Fetch action items 10 action_items = actions.execute_tool( 11 connection_name="grainmcp", 12 identifier="user_123", 13 tool_name="grainmcp_fetch_meeting_action_items", 14 tool_input={"meeting_id": "meeting_abc123"}, 15 ) 16 print(notes, action_items) ``` ### Create a clip and add it to a story Use `grainmcp_create_clip` to extract a video segment from a recording, then `grainmcp_add_clips_to_story` to curate it into a shareable story. * Node.js ```typescript 1 // Step 1 — create a clip 2 const clip = await actions.executeTool({ 3 connectionName: 'grainmcp', 4 identifier: 'user_123', 5 toolName: 'grainmcp_create_clip', 6 toolInput: { 7 meeting_id: 'meeting_abc123', 8 clip_title: 'Customer feedback on pricing', 9 start_ms: 300000, 10 end_ms: 360000, 11 }, 12 }); 13 const clipId = clip.data?.id; 14 15 // Step 2 — add to an existing story 16 await actions.executeTool({ 17 connectionName: 'grainmcp', 18 identifier: 'user_123', 19 toolName: 'grainmcp_add_clips_to_story', 20 toolInput: { 21 story_id: 'story_xyz789', 22 clip_ids: [clipId], 23 }, 24 }); ``` * Python ```python 1 # Step 1 — create a clip 2 clip = actions.execute_tool( 3 connection_name="grainmcp", 4 identifier="user_123", 5 tool_name="grainmcp_create_clip", 6 tool_input={ 7 "meeting_id": "meeting_abc123", 8 "clip_title": "Customer feedback on pricing", 9 "start_ms": 300000, 10 "end_ms": 360000, 11 }, 12 ) 13 clip_id = clip.data.get("id") 14 15 # Step 2 — add to an existing story 16 actions.execute_tool( 17 connection_name="grainmcp", 18 identifier="user_123", 19 tool_name="grainmcp_add_clips_to_story", 20 tool_input={ 21 "story_id": "story_xyz789", 22 "clip_ids": [clip_id], 23 }, 24 ) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Granola connector > Connect to Granola to access AI-generated meeting notes, summaries, transcripts, and attendee data from your workspace. Granola automatically records and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'granola' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'granola_audit_events_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "granola" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="granola_audit_events_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List webhook endpoints, folders, audit events** — List all webhook endpoints configured for the Granola workspace, including their URL, scopes, subscribed event types, and enabled state * **Update webhook endpoint** — Update an existing Granola webhook endpoint’s URL, scopes, subscribed events, folder filter, or enabled state * **Delete webhook endpoint** — Permanently remove a Granola webhook endpoint * **Create webhook endpoint** — Register a new HTTPS webhook endpoint to receive Granola event deliveries (e.g * **Get note transcript, note** — Retrieve the full meeting transcript for a Granola note, paginated with a cursor ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Granola MCP connector > Connect to Granola MCP using OAuth 2.1 with MCP discovery and dynamic client registration. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'granolamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Granola MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'granolamcp_get_account_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "granolamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Granola MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="granolamcp_get_account_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List meeting folders, meetings** — List the user’s Granola meeting folders * **Get account info, meetings, meeting transcript** — Get the email, active workspace, and effective note-access scopes for the Granola account currently connected to this MCP session * **Query granola meetings** — Query Granola about the user’s meetings using natural language ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Greptile MCP connector > AI-powered code search and understanding API that indexes GitHub and GitLab repositories, enabling natural language queries over codebases. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'greptilmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Greptile MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'greptilmcp_list_code_reviews', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "greptilmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Greptile MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="greptilmcp_list_code_reviews", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search knowledge base, greptile comments, custom context** — Case-insensitive substring search across one repository’s knowledge base * **List knowledge bases, knowledge base documents, pull requests** — List the repositories in your organization that have a published Greptile knowledge base — the per-repository documentation Greptile synthesizes from the codebase and consults while reviewing * **Get knowledge base document, merge request, custom context** — Get the markdown body of a single knowledge base document * **Review trigger code** — Trigger a Greptile code review for a pull request * **Create custom context** — Create a new custom context for an organization to guide Greptile’s code review behavior ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # GTmetrix MCP connector > Connect to GTmetrix MCP to analyze web page performance, run speed tests, monitor Core Web Vitals, and get actionable optimization recommendations... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gtmetrixmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize GTmetrix MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gtmetrixmcp_get_account_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gtmetrixmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize GTmetrix MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gtmetrixmcp_get_account_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Reauthenticate records** — Sign in to a GTmetrix account from the current MCP session * **Test start** — Start a new GTmetrix page performance test for a URL * **List pages** — List GTmetrix pages for the authenticated account * **Get test, report history, report har** — Get the current status of a started GTmetrix test ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Gusto MCP connector > Connect to Gusto MCP. Manage employees, contractors, payroll, departments, and company data from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'gustomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Gusto MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'gustomcp_get_company', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "gustomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Gusto MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="gustomcp_get_company", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update payroll** — Update inputs (hours, amounts, memos, PTO, exclusions, payment method) for employees on an unprocessed payroll before running it * **Feedback submit** — Submit user feedback about the Gusto MCP experience, with an optional category and freeform context metadata (e.g * **Search business info** — Resolve free-text business info to canonical codes: type industry returns NAICS industry classifications, type occupation returns BLS occupation codes, matched against the user’s query * **Answer save company onboarding** — Save the answer for one onboarding question\_key * **Run payroll** — Calculate and submit an existing unprocessed payroll by payroll\_uuid * **Time record** — Record time for an employee or contractor (identified by company\_member\_uuid, from list\_time\_records), either adding a new shift or updating an existing one via on\_existing ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # HappyScribe MCP connector > HappyScribe is an AI-powered transcription and translation service. Connect your HappyScribe account to search transcripts, generate meeting summaries... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'happyscribemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize HappyScribe MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'happyscribemcp_get_folder_hierarchy', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "happyscribemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize HappyScribe MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="happyscribemcp_get_folder_hierarchy", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Retranscribe records** — Re-runs automatic transcription (ASR) on the existing media of a transcription already in the workspace, replacing the current transcript in place (the transcription keeps its ID) * **Quotes verify** — REQUIRED for quote extraction: Verifies quote text against the actual transcription content and returns precise timestamps and working links to each quote in the editor * **File upload** — Upload an audio or video file to HappyScribe for transcription * **Update summary template, project notes** — Update an existing summary template * **Template set meeting** — Configure which summary template to use for future meetings * **Search transcriptions, helpdesk** — Search for exact text/keywords within transcription content (like grep) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # HarvestAPI connector > Connect to HarvestAPI to scrape LinkedIn profiles, companies, and job listings, and search for people and jobs using LinkedIn data. Enables AI agents to... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your HarvestAPI credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'harvestapi' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'harvestapi_get_ad', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "harvestapi" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="harvestapi_get_ad", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Employees bulk scrape company** — Bulk-list the employees of one or more LinkedIn companies via HarvestAPI’s dedicated Apify actor, same pattern as the existing Bulk Scrape LinkedIn Profiles tool * **Search leads, services, geo** — Search LinkedIn for leads using advanced filters including company, job title, location, seniority, industry, and experience * **Get profile reactions, profile comments, comment reactions** — Retrieve reactions made by a LinkedIn profile * **Profile scrape** — Scrape a LinkedIn profile by URL or public identifier, returning contact details, employment history, education, skills, and more * **Job scrape** — Retrieve full job listing details from LinkedIn by job URL or job ID * **Company scrape** — Scrape a LinkedIn company page for overview, headcount, employee count range, follower count, locations, specialities, industries, and funding data ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Harvest MCP connector > Harvest is a time tracking and invoicing tool that helps teams track time, manage projects, and create invoices. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'harvestmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Harvest MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'harvestmcp_get_account_settings', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "harvestmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Harvest MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="harvestmcp_get_account_settings", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update time entry, task, project** — Update an existing time entry * **Project unassign user from, remove task from, assign user to** — Remove a user from a project * **Timesheet submit** — Submit a timesheet period for approval * **Feedback submit** — Submit feedback or a support message to Harvest * **Timer stop, start** — Stop the currently running timer for the authenticated user * **Time log** — Log a completed time entry ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Hex MCP connector > Connect to Hex MCP. Create and continue data analysis threads, search projects, and query your data using natural language from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'hexmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Hex MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'hexmcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "hexmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Hex MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="hexmcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search projects** — Search for Hex projects by keyword * **Get thread, me** — Fetch a Hex Thread by its ID, including the latest response and status * **Create thread** — Create a new Hex Thread to ask a question about your data using natural language * **Thread continue** — Continue an existing Hex Thread by adding a new message and triggering the agent to process it ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # HeyReach connector > Connect to HeyReach to manage LinkedIn outreach campaigns, lead lists, and conversations. List campaigns, retrieve leads, monitor campaign progress, and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your HeyReach credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'heyreach' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'heyreach_check_api_key', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "heyreach" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="heyreach_check_api_key", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Campaign resume, pause, add leads to** — Resume a paused, finished, or failed HeyReach campaign so it starts sending outreach actions again * **Create list** — Create a new empty lead list in your HeyReach account * **List add leads to** — Add leads directly to a HeyReach lead list, independent of any campaign * **Get lead, conversations, all linkedin accounts** — Retrieve detailed information about a single HeyReach lead by their LinkedIn profile URL * **Key check api** — Verify that your HeyReach API key is valid and the connection is working ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Higgsfield MCP connector > Connect to Higgsfield MCP to generate AI images and videos, train consistent characters, and manage your creation history across 30+ models including... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'higgsfieldmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Higgsfield MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'higgsfieldmcp_apps_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "higgsfieldmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Higgsfield MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="higgsfieldmcp_apps_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Status website, video analysis, tiktok publish** — Get the website’s deploy status — the live URL and the status of the last deploy * **Secrets website** — Manage a website’s SECRETS (environment variables: API keys, tokens) * **Access website repo** — Get direct git access to a website’s repo to edit it — THE way to get the website’s code * **Db website** — Inspect the website’s database (D1 / SQLite), READ-ONLY * **Change voice** — Replace the spoken voice in a video with a different voice while keeping the original timing and visuals, then re-merge the new audio onto the video * **Predictor virality** — Virality Predictor predicts a video’s virality potential, engagement, attention, audience response, retention risk, hook strength, and creative performance with an interactive dashboard ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # HubSpot connector > Connect to HubSpot CRM. Manage contacts, deals, companies, and marketing automation 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your HubSpot credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'hubspot' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize HubSpot:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call — list CRM owners 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'hubspot_owners_list', 25 toolInput: {}, 26 }) 27 console.log('HubSpot owners:', result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "hubspot" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize HubSpot:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call — list CRM owners 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="hubspot_owners_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print("HubSpot owners:", result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Manage contacts** — create, update, search, and list contacts; batch create, update, upsert, read, and archive * **Manage companies and deals** — create and update company records and deals; batch create, update, upsert, read, and archive * **Manage tickets and tasks** — create and update support tickets; create tasks with due dates and priorities * **Batch operations with inline associations** — create contacts, companies, deals, or tickets and link them to related records in a single call * **Log engagements** — record calls, meetings, notes, and emails against any CRM record * **Search, associate, and extend** — full-text search across all CRM objects, batch-manage associations, list owners, discover properties, and work with custom objects ## Choosing a HubSpot app type [Section titled “Choosing a HubSpot app type”](#choosing-a-hubspot-app-type) HubSpot has three app shapes. The shape you choose determines which OAuth flow, scope format, and Scalekit configuration apply. | App type | OAuth redirect | Scope format | Use with Scalekit | | ------------------------------ | -------------- | --------------------------------------- | ------------------------------------------------- | | Public app | Supported | Modern (`crm.objects.contacts.read`) | Recommended | | Private app | Not supported | N/A — static API token only | Not supported | | Legacy / developer-account app | Supported | Bare strings (`contacts`, `automation`) | Supported — enter bare strings in **Permissions** | **Public apps** are the standard choice for production integrations. They support the OAuth redirect flow that Scalekit manages, and they use the modern dotted scope format. **Private apps** issue static API tokens and have no OAuth redirect endpoint. Scalekit’s HubSpot connector requires an OAuth flow, so Private apps are not compatible. **Legacy apps** (older apps created in HubSpot developer test accounts before the current console) still support OAuth but use an older scope vocabulary. If you already have a legacy app, you can connect it — you just need to enter the older bare scope strings exactly as HubSpot lists them in that app’s **Auth** > **Scopes** page. Legacy app scope strings Legacy HubSpot apps reject the modern `crm.objects.*` format. Copy scope strings from your app’s **Auth** > **Scopes** screen in HubSpot and paste them into Scalekit’s **Permissions** field as-is. ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Required and optional scopes [Section titled “Required and optional scopes”](#required-and-optional-scopes) HubSpot’s OAuth connection requires one scope and supports up to 23 optional scopes. Grant only the scopes your tools actually need — a smaller scope set means a simpler consent screen and a faster app review for public listings. ### Required scope `oauth` — included automatically on every HubSpot connection. You do not need to add it manually. ### Optional scopes Add scopes that match the tools you plan to call. Common choices: | Scope | Enables | | ------------------------------ | ------------------------------------------ | | `crm.objects.contacts.read` | Read contacts | | `crm.objects.contacts.write` | Create and update contacts | | `crm.objects.companies.read` | Read companies | | `crm.objects.companies.write` | Create and update companies | | `crm.objects.deals.read` | Read deals | | `crm.objects.deals.write` | Create and update deals | | `crm.objects.line_items.read` | Read line items | | `crm.objects.line_items.write` | Create and update line items | | `crm.objects.quotes.read` | Read quotes | | `crm.lists.read` | Read contact lists | | `crm.lists.write` | Create and manage contact lists | | `tickets` | Read and write support tickets | | `forms` | Read forms and form submissions | | `automation` | Read and trigger workflows and engagements | | `e-commerce` | Products and orders | See HubSpot’s [scope reference](https://developers.hubspot.com/docs/api/working-with-oauth#scopes) for the full list. ### Configure optional scopes in your HubSpot app In your HubSpot app, go to **Auth** > **Auth settings** > **Scopes**. You’ll see three categories: **Required scopes** (always requested), **Conditionally required scopes**, and **Optional scopes** (requested only when the user’s account has access to them). ![HubSpot Scopes page showing Required, Conditionally required, and Optional scopes sections](/.netlify/images?url=_astro%2Foptional-scopes.BWMN1mMm.png\&w=2310\&h=441\&dpl=6aaa70ad2ea7b40008ad2afd) Click **Add new scope** and select the optional scopes your app needs. Optional scopes let users without access to a feature still install your app — HubSpot simply skips those scopes at consent time. ### Enable the same optional scopes in Scalekit 1. Open the connection in **AgentKit** > **Connections**. 2. In the **Permissions** field, enter the scopes you need, space-separated. Example for a read-only CRM flow: `crm.objects.contacts.read crm.objects.companies.read crm.objects.deals.read`. 3. Make sure the scope set here matches exactly what you’ve configured in your HubSpot app. A mismatch causes an `invalid_scope` error when the user authorizes. ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most HubSpot batch and update tools require record IDs. Always fetch IDs from the API — never guess or hard-code them. | Resource | Tool to get ID | Field in response | | ----------------------- | ---------------------------------------------------- | ------------------------ | | Contact ID | `hubspot_contacts_search` or `hubspot_contacts_list` | `results[].id` | | Company ID | `hubspot_companies_search` | `results[].id` | | Deal ID | `hubspot_deals_search` | `results[].id` | | Ticket ID | `hubspot_tickets_search` | `results[].id` | | Line Item ID | `hubspot_deal_line_items_get` | `results[].id` | | Product ID | `hubspot_products_list` | `results[].id` | | Owner ID | `hubspot_owners_list` | `results[].id` | | Pipeline ID | `hubspot_deal_pipelines_list` | `results[].id` | | Pipeline Stage ID | `hubspot_deal_pipelines_list` | `results[].stages[].id` | | Custom Object Type ID | `hubspot_schemas_list` | `results[].objectTypeId` | | Custom Object Record ID | `hubspot_custom_object_records_search` | `results[].id` | | Quote ID | `hubspot_quote_get` | `id` | ### Association type IDs When linking records, use the correct `association_type_id` for the object pair: | From → To | Association Type ID | | --------------------------- | ------------------- | | Contact → Company (primary) | `1` | | Contact → Company | `279` | | Contact → Deal | `4` | | Contact → Ticket | `15` | | Deal → Contact | `3` | | Deal → Company | `5` | | Ticket → Contact | `16` | | Ticket → Company | `340` | | Line Item → Deal | `20` | | Company → Contact | `280` | | Company → Deal | `6` | ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # HubSpot MCP connector > Connect to HubSpot MCP. Manage CRM contacts, companies, deals, landing pages, campaigns, and analytics from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your HubSpot MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'hubspotmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize HubSpot MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'hubspotmcp_get_campaign_analytics', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "hubspotmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize HubSpot MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="hubspotmcp_get_campaign_analytics", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read campaign data** — Reads campaign data using one of three operations selected by the operation field * **Onboarding manage** — Assess a portal’s CRM onboarding status and guide the user through the next onboarding step * **Objects manage campaign, manage crm** — Creates or updates HubSpot marketing campaigns and manages asset associations * **Get campaign attribution reports, user details, properties** — REQUIRED FIRST STEP: before your first call, invoke tool\_guidance for “get\_campaign\_attribution\_reports” and follow it * **Schema discover hubspot** — Searches HubSpot schema to discover available data types or look up known types directly * **Guidance tool** — Retrieve usage instructions and guidance for one or more HubSpot MCP tools ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Hugging face MCP connector > Connect to Hugging Face MCP. Search and manage models, datasets, spaces, and collections on the Hugging Face Hub. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'huggingfacemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Hugging face MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'huggingfacemcp_hf_whoami', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "huggingfacemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Hugging face MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="huggingfacemcp_hf_whoami", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Fs hf** — Navigate and search Hugging Face Hub resources (models, datasets, spaces, buckets, collections, papers, and documentation) through a virtual filesystem interface over hf:// URIs, using ls, cat, attach, stat, find, and search commands * **Search space, paper, hub repo** — Search Hugging Face Spaces by query and return matching spaces with relevance scores * **Details hub repo** — Retrieve details for one or more Hugging Face Hub repositories by their IDs * **Whoami hf** — Return the currently authenticated Hugging Face user’s profile information * **Query hf hub** — Ask a natural language question about the Hugging Face Hub and get an AI-generated answer * **Fetch hf doc** — Fetch the content of a Hugging Face documentation page by URL, with optional character offset for pagination ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # IcePanel MCP connector > Connect your IcePanel software architecture models to AI agents. Query and update your C4 model landscapes — systems, apps, components, connections, and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your IcePanel MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'icepanelmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize IcePanel MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'icepanelmcp_icepanel_listadrs', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "icepanelmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize IcePanel MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="icepanelmcp_icepanel_listadrs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Listtechnologies icepanel** — List technologies from the catalog and organization * **Listconnections icepanel** — List connections where a model object is the origin or target * **Landscapesearch icepanel** — Search across all landscape entities (model objects, connections, diagrams, flows) by name * **Updateconnection icepanel** — Update a connection in the landscape * **Listtags icepanel** — List tags and tag groups in the landscape * **Getadrdetails icepanel** — Get detailed information about a specific Architecture Decision Record (ADR) including its full content, status history, and related items ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Find a landscape and list its model objects Most IcePanel tools require a `landscapeId`. Use `icepanelmcp_icepanel_landscapesearch` to find landscapes by name or description, then pass the returned `id` to subsequent tools. * Node.js ```typescript 1 // Step 1 — find the landscape 2 const results = await actions.executeTool({ 3 connectionName: 'icepanelmcp', 4 identifier: 'user_123', 5 toolName: 'icepanelmcp_icepanel_landscapesearch', 6 toolInput: { query: 'production' }, 7 }); 8 const landscapeId = results.landscapes[0].id; 9 10 // Step 2 — list all model objects in the landscape 11 const objects = await actions.executeTool({ 12 connectionName: 'icepanelmcp', 13 identifier: 'user_123', 14 toolName: 'icepanelmcp_icepanel_listmodelobjects', 15 toolInput: { landscapeId }, 16 }); 17 console.log(objects); ``` * Python ```python 1 # Step 1 — find the landscape 2 results = actions.execute_tool( 3 connection_name="icepanelmcp", 4 identifier="user_123", 5 tool_name="icepanelmcp_icepanel_landscapesearch", 6 tool_input={"query": "production"}, 7 ) 8 landscape_id = results["landscapes"][0]["id"] 9 10 # Step 2 — list all model objects in the landscape 11 objects = actions.execute_tool( 12 connection_name="icepanelmcp", 13 identifier="user_123", 14 tool_name="icepanelmcp_icepanel_listmodelobjects", 15 tool_input={"landscapeId": landscape_id}, 16 ) 17 print(objects) ``` ### Create an architecture decision record Use `icepanelmcp_icepanel_createadr` to log an ADR directly from your agent. Provide `name` and optionally `description` and `content`. The `content` field supports Markdown — use it to structure context, decision, and consequences sections. * Node.js ```typescript 1 const adr = await actions.executeTool({ 2 connectionName: 'icepanelmcp', 3 identifier: 'user_123', 4 toolName: 'icepanelmcp_icepanel_createadr', 5 toolInput: { 6 name: 'Use event sourcing for order history', 7 description: 'Decision to adopt event sourcing for the Orders bounded context', 8 content: '## Context\nWe need a reliable audit trail for order state changes.\n\n## Decision\nAdopt event sourcing for the Orders bounded context.\n\n## Consequences\nIncreased storage; simpler replay and debugging.', 9 }, 10 }); 11 console.log(adr.id); ``` * Python ```python 1 adr = actions.execute_tool( 2 connection_name="icepanelmcp", 3 identifier="user_123", 4 tool_name="icepanelmcp_icepanel_createadr", 5 tool_input={ 6 "name": "Use event sourcing for order history", 7 "description": "Decision to adopt event sourcing for the Orders bounded context", 8 "content": "## Context\nWe need a reliable audit trail for order state changes.\n\n## Decision\nAdopt event sourcing for the Orders bounded context.\n\n## Consequences\nIncreased storage; simpler replay and debugging.", 9 }, 10 ) 11 print(adr["id"]) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # IGPT MCP connector > IGPT is an AI assistant platform that exposes its capabilities via an MCP server, enabling agents to interact with AI-powered tools and workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'igptmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize IGPT MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'igptmcp_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "igptmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize IGPT MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="igptmcp_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search records** — Search connected datasources which include documents and messages * **Ask records** — Sends user question to backend and returns answer based on connected datasources which include documents and messages ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Intercom connector > Connect to Intercom. Send messages, manage conversations, and interact with users and contacts. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Intercom credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'intercom' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Intercom:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'intercom_list_activity_log_event_types', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "intercom" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Intercom:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="intercom_list_activity_log_event_types", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update company, visitor, ticket type attribute** — Update a single company using its Intercom-provisioned ID * **Search activity logs, tickets, conversations** — Search admin activity logs with structured filters (date range, event types, pagination), distinct from the existing plain date-range list tool * **Companies scroll** — Scroll over all companies in the workspace using Intercom’s Scroll API, an efficient mechanism for iterating over large company datasets without the 10,000-record limit of the standard list endpoints * **List office hours schedules, macros, external pages** — List all office-hours schedules configured for the workspace * **Get macro** — Retrieve a single macro (saved reply) by its ID, subject to the same team-visibility rules as the Intercom inbox * **Create office hours schedule, external page, data event summaries** — Create a new office-hours schedule defining the recurring weekly hours the workspace (or a team) is open ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Jam MCP connector > Connect to Jam MCP. Access bug reports, console logs, network requests, user events, and video transcripts from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'jammcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Jam MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'jammcp_fetch', 25 toolInput: { id: 'https://example.com/id' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "jammcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Jam MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"https://example.com/id"}, 27 tool_name="jammcp_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Updatejam records** — Update a Jam bug report * **Search records** — Search for a Jam by extracting a UUID from a query string, jam.dev URL, or pasted text and returning matching Jam metadata * **Listmembers records** — List team members with optional search and pagination * **Listjams records** — List Jam bug reports with filtering and pagination * **Listfolders records** — List folders in the team with optional search and pagination * **Getvideotranscript records** — Retrieve the speech transcript (captions) from a video Jam recording in WebVTT format with timestamps ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Jentic MCP connector > Connect to Jentic MCP. Search available API actions, load execution details, manage credentials, and execute API operations from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'jenticmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Jentic MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'jenticmcp_list_credentials', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "jenticmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Jentic MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="jenticmcp_list_credentials", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search apis** — Search for available API actions based on a natural language description of what the user wants to do * **Info load execution** — Retrieve detailed information about a specific action before running it, including required inputs and parameters * **List credentials** — List all API credentials the authenticated agent has access to, showing which APIs are available to use * **Execute records** — Execute a specific API action using provided parameters, including any required inputs for the operation ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Jiminny connector > Connect with Jiminny to access call recordings, transcripts, coaching insights, and conversation intelligence data. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Jiminny credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'jiminny' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'jiminny_activities_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "jiminny" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="jiminny_activities_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Upload zapier activity, activity** — Upload a call or meeting activity to Jiminny by providing a publicly accessible recording URL instead of a file upload, returning the new or existing activity ID * **List webhooks, automated reports, ai scorecards** — Retrieve all webhook subscriptions registered for the authenticated organization, including their trigger, destination URL, and external ID * **Get automated report status, automated report, automated report download** — Lightweight poll endpoint that returns the generation status of an automated report’s latest result, without the full report payload * **Xyz test tool** — Test * **Create webhook** — Create a webhook subscription that sends event payloads to a destination URL when a specified trigger occurs in Jiminny * **Delete webhook** — Delete an existing webhook subscription by its UUID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Jira connector > Connect to Jira. Manage issues, projects, workflows, and agile development processes 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Jira credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'jira' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Jira:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'jira_all_users_default_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "jira" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Jira:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="jira_all_users_default_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read issues** — fetch issue details, comments, attachments, and linked items * **Create and update issues** — file bugs, stories, and tasks; update status and assignees * **Manage projects** — list projects, sprints, and boards * **Search with JQL** — execute Jira Query Language searches for advanced filtering ## Common workflows [Section titled “Common workflows”](#common-workflows) **Don’t worry about the Jira cloud ID in the path.** Scalekit resolves `{{cloud_id}}` from the connected account configuration automatically. A request with `path="/rest/api/3/myself"` is routed to the correct Atlassian instance without any extra setup. ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Jira Service Management connector > Connect to Jira Service Management. Manage customer requests, service desks, organizations, knowledge base articles, SLAs, and queues 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'jiraservicemanagement' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Jira Service Management:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'jiraservicemanagement_assets_workspaces_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "jiraservicemanagement" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Jira Service Management:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="jiraservicemanagement_assets_workspaces_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create temporary attachment, request type, request comment** — Upload a file to a service desk as a temporary attachment * **List sla information, service desks, service desk request types** — Retrieve all SLA (Service Level Agreement) records for a Jira Service Management customer request * **Get sla information, service desk, request type property** — Retrieve the details of a single SLA (Service Level Agreement) metric on a Jira Service Management customer request, identified by the SLA metric ID * **Remove service desk organization, service desk customers, request participants** — Remove an organization from a service desk * **Add service desk organization, service desk customers, request participants** — Add an organization to a service desk, granting members of that organization access to raise and view requests on the service desk’s portal * **Unsubscribe request** — Unsubscribe the authenticated user from notifications on a customer request ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Jotform MCP connector > Connect to Jotform MCP. Create and edit forms, retrieve submissions, assign forms, and search assets from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'jotformmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Jotform MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'jotformmcp_fetch', 25 toolInput: { id: 'YOUR_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "jotformmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Jotform MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"YOUR_ID"}, 27 tool_name="jotformmcp_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search records** — Search Jotform assets by query with optional filters, ordering, and limit * **Get submissions** — List submission IDs for a form with optional filters * **Fetch records** — Fetch metadata and information for a Jotform form by its ID or URL * **Form edit, assign** — Edit an existing form using a natural-language instruction * **Create form** — Create a new Jotform form based on a natural-language description * **Submissions analyze** — Perform AI-powered analysis on one or more forms’ submissions using a natural-language query ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Kit MCP connector > Connect to Kit MCP. Manage email subscribers, sequences, broadcasts, tags, and forms for your email marketing workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'kitmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Kit MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'kitmcp_get_creator_profile', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "kitmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Kit MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="kitmcp_get_creator_profile", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tag name, product, landing page** — \[Tags] Rename an existing tag * **Subscriber remove tag from, tag** — \[Tags] Remove a tag from a subscriber * **List tax codes, tags for a subscriber, subscribers for tag** — \[Products] List the Kit tax codes used to classify a product’s tax category, i.e * **Get stats for a list of broadcasts, stats for a broadcast, product** — \[Broadcasts] Performance analytics across many broadcasts at once * **Create product, landing page, webhook** — \[Products] Create a Commerce product the creator can sell — a digital download, an external URL, a paid newsletter, or a tip jar * **Subscribers bulk remove tags from, filter, bulk tag** — \[Tags] Remove a tag from multiple subscribers in a single call ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Klaviyo MCP connector > Connect to Klaviyo MCP. Report, strategize & create with real-time Klaviyo data 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'klaviyomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Klaviyo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'klaviyomcp_get_account_details', 25 toolInput: { model: 'YOUR_MODEL' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "klaviyomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Klaviyo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"model":"YOUR_MODEL"}, 27 tool_name="klaviyomcp_get_account_details", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Manage campaigns** — create campaigns, assign email templates to campaign messages, and retrieve campaign details and performance reports * **Manage profiles** — create, update, and retrieve customer profiles; subscribe and unsubscribe profiles from marketing channels * **Analyze flows and metrics** — fetch flow details and reports; query and aggregate event metric data with custom dimensions * **Manage email templates** — create and retrieve reusable email templates for campaigns * **Browse lists and segments** — retrieve lists, segments, and catalog items to understand your audience * **Manage translations** — create, update, delete, and list translation collections for multi-language content ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Kling AI MCP connector > Kling AI is a video and image generation platform. This MCP connector exposes Kling AI capabilities — including video generation and image generation —... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'klingmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Kling AI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'klingmcp_kling_list_actions', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "klingmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Kling AI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="klingmcp_kling_list_actions", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Photo kling talking** — Animate a portrait photo to match a provided audio track (talking-photo) * **Sync kling lip** — Synchronize lip movements in a video to match a given audio track or text * **List kling** — List all available Kling models for video generation * **Get kling** — Query multiple video generation tasks at once * **Image kling generate video from** — Generate AI video using reference images as start and/or end frames * **Video kling generate, kling extend** — Generate AI video from a text prompt using Kling ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Latch Bio MCP connector > Latch Bio is a cloud bioinformatics platform for running computational biology workflows. Its MCP server lets AI agents list and retrieve files, manage... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'latchbiomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Latch Bio MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'latchbiomcp_list_executions', 25 toolInput: { rationale: 'YOUR_RATIONALE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "latchbiomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Latch Bio MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"rationale":"YOUR_RATIONALE"}, 27 tool_name="latchbiomcp_list_executions", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List workspaces, workflows, files** — Lists Latch workspaces the current user can access * **Workflow launch** — Launch a bioinformatics workflow on Latch * **Get workflow schema, task logs, file** — Fetch the launch metadata and parameter schema for a workflow ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LaunchDarkly MCP connector > Connect to LaunchDarkly's hosted MCP server to manage feature flags, experiments, and release controls directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'launchdarklymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LaunchDarkly MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'launchdarklymcp_find_members', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "launchdarklymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LaunchDarkly MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="launchdarklymcp_find_members", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update segment targets, segment rules, alert** — Add or remove individual context keys from a segment’s included or excluded lists * **Alert toggle** — Enable or disable an observability alert without changing its configuration * **Config toggle agentcontrol, setup agentcontrol, setup ai** — Turn an AgentControl Config’s targeting on or off in a specific environment * **Search docs, contexts** — Search LaunchDarkly documentation to retrieve authoritative reference material for flags, targeting rules, experiments, segments, AgentControl configs, SDKs, API fields, rollouts, metrics, and more * **Policies match release** — Resolve which release policies would govern a flag in a given environment — a read-only dry-run of the server-side policy matching logic * **List segments, projects, alerts** — List segments in a project environment ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LeadBoxer MCP connector > Connect to LeadBoxer MCP to identify anonymous website visitors and enrich them with firmographic data. LeadBoxer is a B2B lead generation and website... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'leadboxermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LeadBoxer MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'leadboxermcp_list_specs', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "leadboxermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LeadBoxer MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="leadboxermcp_list_specs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search endpoints** — Performs a deep search through paths, operations, and parameters to discover relevant API endpoints * **List specs, endpoints** — Lists all available OpenAPI specs * **Get endpoint** — Gets detailed information about a specific API endpoint, including security schemes and servers * **Execute request** — Executes an API request with a given HAR request object ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Leadfeeder MCP connector > Connect to Leadfeeder's MCP server to identify website visitors, track B2B leads, and surface company-level intent data directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'leadfeedermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Leadfeeder MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'leadfeedermcp_get_account_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "leadfeedermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Leadfeeder MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="leadfeedermcp_get_account_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Usage records** — Retrieve current API usage and credit consumption for a Leadfeeder account * **Update web visits custom feed, tag, list** — Update the configuration of an existing web visit custom feed * **Company unassign tags from, assign tags to** — Remove one or more tags from a Leadfeeder company * **Search web visits, contacts, companies signals** — Search and filter web visit records to identify companies that visited your website * **Lists remove contact from, remove company from, add contact to** — Allows the removal of this contact from one or more lists * **Companies match** — Find matching companies based on the provided input parameters ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LeadIQ connector > Connect to LeadIQ to search and enrich B2B contacts and companies with verified emails, direct dials, and mobile numbers. Build prospect lists and power... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your LeadIQ credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search contacts** — look up verified work emails, direct dials, and mobile numbers by LinkedIn URL, email, or name * **Preview before consuming credits** — check whether LeadIQ has a work email or phone for a person without spending credits * **Enrich companies** — fetch firmographics including industry, employee count, and location by domain or name * **Advanced prospecting** — filter contacts by title, seniority, industry, company size, and location; get results flat or grouped by company * **Manage prospect lists** — create lists, add contacts, and retrieve saved prospects (requires Prospector plan) * **Monitor quota** — check API credit usage, plan limits, and subscription status before making credit-consuming calls ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LeadIQ MCP connector > Connect to LeadIQ via MCP to search and enrich B2B contacts and companies. Access real-time prospect data, company intelligence, and email/phone... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'leadiqmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LeadIQ MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'leadiqmcp_check_credits', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "leadiqmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LeadIQ MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="leadiqmcp_check_credits", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Email verify prospect, verify** — Re-verify the work email already stored on a saved Prospector prospect and persist the updated status * **Search prospects** — Search the user’s saved Prospector prospects across all lists by email or full name * **Get prospect list, prospect** — Fetch a single LeadIQ Prospector list by id, including its paginated prospect records * **People find, enrich** — Discover new leads in LeadIQ’s B2B database matching ICP criteria — filter by title, seniority, role, industry, technology stack, company size, revenue, funding, location, and hiring or promotion signals * **Changes find job** — Discover people who recently changed jobs or were promoted, matched against ICP criteria * **Companies find, enrich** — Discover companies matching ICP criteria in LeadIQ’s B2B database — filter by industry, size, revenue, funding, technology stack, location, and more ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Legal Data Hunter MCP connector > Connect to Legal Data Hunter MCP. Search and explore indexed legal data sources worldwide, tracking case law, courts, dockets, and legal data coverage... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'legaldatahuntermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Legal Data Hunter MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'legaldatahuntermcp_get_filters', 25 toolInput: { source: 'YOUR_SOURCE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "legaldatahuntermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Legal Data Hunter MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"source":"YOUR_SOURCE"}, 27 tool_name="legaldatahuntermcp_get_filters", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search records** — Search the world’s fastest-growing legal database using hybrid semantic and keyword matching * **Reference resolve** — Resolve a loose legal citation or reference to the exact matching document(s) * **Issue report source** — Report an issue with a data source to the platform maintainer * **Get filters, document** — Get available filter values for a specific data source * **Sources discover** — List all data sources available for a specific country * **Countries discover** — List all available countries with their document counts and source counts ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Lemlist MCP connector > Connect to Lemlist MCP. Manage outbound sales campaigns, leads, email sequences, and LinkedIn outreach from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'lemlistmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Lemlist MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'lemlistmcp_check_domain_health', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "lemlistmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Lemlist MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="lemlistmcp_check_domain_health", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update watch list, task content, task** — Update an existing watch list * **List transfer campaign leads to, remove contacts from, watch list signals** — Add every lead of a campaign to a CRM contact list, in one call * **Lists suggest watch** — Generate AI-suggested watch lists for the current team * **Strategy set campaign sender** — Set the sender-assignment strategy for a campaign — the algorithm that decides which sender (user) is attached to each lead at launch * **Variant set ab** — Set or update the A/B test variant B (subject and/or body) of an EMAIL sequence step * **Send task, message** — Send one OR many message-based tasks now, OR — for a manual campaign step — schedule it via the campaign and mark it done (the “Send & mark done” / “Schedule & mark done” actions on the Tasks / Focus page) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LILT MCP connector > LILT is an enterprise translation platform that combines AI speed with human expertise to deliver accurate, domain-specific translations at scale. This... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'liltmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LILT MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'liltmcp_get_credit_balance_information', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "liltmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LILT MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="liltmcp_get_credit_balance_information", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **World hello** — Returns a friendly hello world message * **File upload** — Upload a file to LILT for translation * **Text translate** — Translates text using LILT’s instant translate API * **Verification translate files with** — Create a verified translation job assigned to professional LILT linguists for file translation * **List resources** — Lists and filters LILT jobs or translation models * **Get credit balance information** — Retrieves all available credit balances for the authenticated user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Linear connector > Connect to Linear. Manage issues, projects, sprints, and development workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Linear credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'linear' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Linear:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'linear_attachments_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "linear" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Linear:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="linear_attachments_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read issues** — fetch issues, projects, cycles, and team details * **Create and update issues** — file new issues, update status, set priority, and assign teammates * **Manage projects** — create and update project metadata and milestones * **Search** — find issues by keyword, assignee, label, or state ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most Linear tools require one or more IDs. Always fetch IDs from the API — never guess or hard-code them. | Resource | Tool to get ID | Field in response | | ----------------- | --------------------------------------------- | ------------------------------ | | Team ID | `linear_teams_list` | `teams.nodes[].id` | | Issue ID | `linear_issues_list` or `linear_issue_search` | `issues.nodes[].id` | | Project ID | `linear_projects_list` | `projects.nodes[].id` | | Cycle ID | `linear_cycles_list` | `cycles.nodes[].id` | | Label ID | `linear_labels_list` | `issueLabels.nodes[].id` | | Workflow State ID | `linear_workflow_states_list` | `workflowStates.nodes[].id` | | User ID | `linear_users_list` | `users.nodes[].id` | | Comment ID | `linear_comments_list` | `comments.nodes[].id` | | Attachment ID | `linear_issue_get` (include attachments) | `issue.attachments.nodes[].id` | | Webhook ID | `linear_webhooks_list` | `webhooks.nodes[].id` | | Milestone ID | `linear_project_milestones_list` | `projectMilestones.nodes[].id` | | Roadmap ID | `linear_roadmaps_list` | `roadmaps.nodes[].id` | ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Linear MCP connector > Connect to Linear's hosted MCP server to manage issues, projects, cycles, and comments directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'linearmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Linear MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'linearmcp_get_workspace', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "linearmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Linear MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="linearmcp_get_workspace", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Review submit diff** — Approve a Linear diff, request changes, or submit a review comment * **Note save release** — Create or update release notes * **Release save** — Create or update a release * **Initiative save** — Create or update a Linear initiative * **Comment save diff, save** — Create, reply to, or edit a comment or persisted draft on a Linear diff * **Need save customer** — Create or update a customer need (request) in Linear ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LinkedIn connector > Connect to LinkedIn to manage posts, ads, organizations, analytics, and professional profiles from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'linkedin' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LinkedIn:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'linkedin_ad_accounts_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "linkedin" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LinkedIn:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="linkedin_ad_accounts_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update post, ad account, creative** — Partially update the commentary, visibility, or call-to-action of an existing LinkedIn post * **Get organization share statistics, organization follower statistics, asset** — Get aggregate engagement statistics (impressions, clicks, likes, comments, shares) across all posts shared by a LinkedIn organization page, optionally scoped to a time range * **List organization notifications, lead forms, lead form responses** — Pull notifications (likes, comments, shares, and mentions) on an organization’s posts from the last 60 days, to monitor engagement on a LinkedIn Company Page * **Delete creative, campaign group, post** — Delete a DRAFT LinkedIn ad creative * **Remove ad account user** — Revoke a member’s access to a LinkedIn ad account * **Add ad account user** — Assign or update a member’s role on a LinkedIn ad account, granting them Campaign Manager access ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LinklyHQ MCP connector > LinklyHQ is a URL shortening and link management platform offering click analytics, custom domains, UTM tracking, QR codes, and webhook integrations for... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your LinklyHQ MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'linklymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LinklyHQ MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'linklymcp_get_analytics', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "linklymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LinklyHQ MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="linklymcp_get_analytics", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update workspace, link, domain favicon** — Update workspace settings including the workspace name and webhook notification URL * **Webhook unsubscribe, unsubscribe link, subscribe** — Unsubscribe a webhook URL from workspace-level click events * **Authentication test** — Test API authentication with LinklyHQ * **Search links** — Search for links by name, destination URL, or note * **Ping records** — Health check for the LinklyHQ MCP server * **List workspaces, webhooks, links** — Return details of the authenticated LinklyHQ workspace, including ID and name ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Check authentication status Use `linklymcp_test_authentication` to verify the connection is active and your credentials are valid. * Node.js ```typescript 1 const result = await actions.executeTool({ 2 connectionName: 'linklymcp', 3 identifier: 'user_123', 4 toolName: 'linklymcp_test_authentication', 5 toolInput: {}, 6 }); 7 console.log(result); ``` * Python ```python 1 result = actions.execute_tool( 2 connection_name="linklymcp", 3 identifier="user_123", 4 tool_name="linklymcp_test_authentication", 5 tool_input={}, 6 ) 7 print(result) ``` ### Create a short link with UTM tracking Use `linklymcp_create_link` to shorten a URL and attach UTM parameters for campaign tracking. * Node.js ```typescript 1 const link = await actions.executeTool({ 2 connectionName: 'linklymcp', 3 identifier: 'user_123', 4 toolName: 'linklymcp_create_link', 5 toolInput: { 6 url: 'https://example.com/landing-page', 7 name: 'Summer Campaign', 8 utm_source: 'newsletter', 9 utm_medium: 'email', 10 utm_campaign: 'summer2024', 11 }, 12 }); 13 console.log(link.full_url); ``` * Python ```python 1 link = actions.execute_tool( 2 connection_name="linklymcp", 3 identifier="user_123", 4 tool_name="linklymcp_create_link", 5 tool_input={ 6 "url": "https://example.com/landing-page", 7 "name": "Summer Campaign", 8 "utm_source": "newsletter", 9 "utm_medium": "email", 10 "utm_campaign": "summer2024", 11 }, 12 ) 13 print(link["full_url"]) ``` ### Get click analytics by dimension Use `linklymcp_get_analytics_by` to break down click counts by country, browser, or platform over a date range. * Node.js ```typescript 1 const analytics = await actions.executeTool({ 2 connectionName: 'linklymcp', 3 identifier: 'user_123', 4 toolName: 'linklymcp_get_analytics_by', 5 toolInput: { 6 counter: 'country', 7 start: '2024-01-01', 8 end: '2024-01-31', 9 }, 10 }); 11 console.log(analytics); ``` * Python ```python 1 analytics = actions.execute_tool( 2 connection_name="linklymcp", 3 identifier="user_123", 4 tool_name="linklymcp_get_analytics_by", 5 tool_input={ 6 "counter": "country", 7 "start": "2024-01-01", 8 "end": "2024-01-31", 9 }, 10 ) 11 print(analytics) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ListenLabs MCP connector > Listen Labs is a qualitative research platform for creating, launching, and analyzing studies with AI assistance. This MCP connector gives AI agents... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'listenlabsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ListenLabs MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'listenlabsmcp_list_creatable_orgs', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "listenlabsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ListenLabs MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="listenlabsmcp_list_creatable_orgs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Study move, publish, launch** — Move a study into a folder, or back out to the dashboard root * **Folder manage** — Create, rename, re-nest, or delete a dashboard folder * **Search across studies** — Search across study metadata using a text query * **List studies, creatable orgs** — List studies accessible to the authenticated user * **Get study state, study responses, study analysis** — Return the current state of a study — title, audience, study guide, questions, screener, and recruitment details * **Create study** — Start a new guided user-interview study ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # LogRocket MCP connector > Connect to LogRocket to access session data, query analytics, investigate user-reported issues, and detect regressions directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'logrocketmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize LogRocket MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'logrocketmcp_list_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "logrocketmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize LogRocket MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="logrocketmcp_list_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sessions watch, find** — Use this to analyze one or more LogRocket sessions, each identified by its recording ID and session ID * **Get network entries** — Use this to retrieve raw network request and response pairs recorded during a single LogRocket session, identified by its recording ID and session ID, as a HAR 1.2 document * **Issues find** — Use this to list a LogRocket project’s issues * **Metric build** — Use this to query LogRocket analytics data * **Logrocket use** — Process a natural language query against LogRocket data — sessions, metrics, and issues * **List projects, organizations** — List all projects within a LogRocket organization ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Lokalise connector > Connect to Lokalise to manage software and content localization: projects, translation keys, translations, languages, comments, contributors, glossary... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'lokalise' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'lokalise_list_payment_cards', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "lokalise" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="lokalise_list_payment_cards", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **File upload** — Upload a file to a Lokalise project for import, sending its content as a base64-encoded string alongside its filename and language code * **Update webhook, translation, team user** — Update an existing webhook’s URL, branch scope, subscribed events, or language mappings on a Lokalise project * **Snapshot restore** — Restore a Lokalise snapshot into a new project, seeded with the snapshot’s saved keys, translations, and settings, inside the same team as the original project * **Group remove projects from, remove members from, add projects to** — Remove one or more projects from a user group in a Lokalise team, revoking the group’s members’ access to those projects * **Secret regenerate webhook** — Regenerate the signing secret for an existing webhook on a Lokalise project * **List webhooks, translations, translation providers** — List all webhooks configured on a Lokalise project ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Loops MCP connector > Connect to Loops MCP. Create and manage loops and tasks, set priorities, track work queue stats, and ship completed loops from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'loopsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Loops MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'loopsmcp_get_loop_queue', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "loopsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Loops MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="loopsmcp_get_loop_queue", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update task, bulk** — Update a task’s title, body, status, priority, due date, or loop assignment * **Loop ship, reopen, close** — Mark a loop as shipped and notify all members via email * **Priority set loop** — Set the numeric priority of a loop in the work queue (lower number = higher priority) * **Loops reorder** — Bulk reorder loops in the work queue by passing an array of loop IDs in the desired priority order * **List tasks, loops** — List unassigned tasks in the workspace, optionally filtered by status or priority * **Get workspace, workflow, task** — Get workspace details including the AI context (project-level agent instructions) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Lucid MCP connector > Connect to Lucid. Create and edit Lucidchart diagrams, Lucidspark boards, and Lucidscale visualizations from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'lucidmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Lucid MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'lucidmcp_get_mcp_resource', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "lucidmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Lucid MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="lucidmcp_get_mcp_resource", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Comment post document thread** — Post a new comment to an existing collaboration thread on a Lucid document * **Update lucid** — Rename a Lucid folder or move it to a different parent * **Feedback lucid submit** — Submit user feedback, a bug report, or a feature request about the Lucid MCP server to Lucid’s product team * **Library lucid shape** — Discover shapes/blocks available to insert into a Lucid document, by library, group, or search term * **Details lucid shape** — Get default size, colors, and text-area/advanced properties for one or more Lucid shape classes * **Search lucid** — Locate regions of a Lucid document that contain specific text, returning page/region indexes you can pass to lucidmcp\_fetch ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Lunarcrush MCP connector > Connect to LunarCrush MCP. Access social intelligence, sentiment analytics, and market data for crypto assets from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'lunarcrushmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Lunarcrush MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'lunarcrushmcp_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "lunarcrushmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Lunarcrush MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="lunarcrushmcp_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Series topic time, keyword time, creator time** — Get historical time-series social metrics for a social topic, keyword, cryptocurrency, or stock * **Posts topic, keyword, creator** — Get top social posts by interactions for a topic over a given time period * **Topic records** — Get a summary snapshot of all social metrics and insights for any social topic, keyword, or asset * **Stocks records** — Get a list of stocks sorted by social metrics and optionally filtered by sector * **Search records** — Search for any keyword or account and return matching topics, creators, and assets * **Post records** — Get details for a specific social post by network and post ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Lusha MCP connector > Connect to Lusha MCP. Search and enrich B2B contacts and companies, find lookalikes, run prospecting searches, and access intent and activity signals from... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Lusha MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'lushamcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'lushamcp_contacts_search', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "lushamcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="lushamcp_contacts_search", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search website visits, prospecting contact, prospecting company** — Rank companies that visited the account’s tracked websites by visit engagement * **Update table** — Rename a Workspace table, change its visibility, or archive/unarchive it * **Status table** — Return one Workspace table’s entity count and per-column run aggregates (processing/success/failed rows) * **Run table** — Run (populate) a Workspace table column across all, missing-only, or specific rows * **Entities table remove, table add** — Remove rows (by Lusha entity id) from a Workspace table * **Column table remove, table add** — Remove a non-default column from a Workspace table ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Magic Patterns MCP connector > Connect to Magic Patterns, the AI-powered UI design tool. Generate, edit, and manage design components and artifacts from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'magicpatternsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Magic Patterns MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'magicpatternsmcp_list_design_systems', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "magicpatternsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Magic Patterns MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="magicpatternsmcp_list_design_systems", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Files write design system, write artifact** — Creates or overwrites files in a design system * **Read design system files, recent message history, artifact files** — Reads the contents of one or more files from a design system’s active artifact, such as components/``/index.tsx, index.css, tailwind.config.js, or rules/``.md * **System publish design** — Publishes the design system’s active artifact as a new immutable version * **Update inspiration** — Revises a single already-filled concept of a Magic Patterns inspiration document in place, replacing its html (and optionally its name/description) * **Variants inspiration clear** — Resets every concept of an existing Magic Patterns inspiration document back to an empty placeholder, dropping each concept’s html and its pre-created ‘Iterate’ room * **Variant inspiration add** — Fills in one concept of an existing Magic Patterns inspiration document with its self-contained HTML ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mailchimp connector > Connect to Mailchimp to manage audiences, campaigns, templates, automations, and reports. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Mailchimp credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mailchimp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mailchimp:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mailchimp_account_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mailchimp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mailchimp:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mailchimp_account_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search member** — Search for members by email or name fragment across every audience in the account, or restrict the search to one audience * **List webhooks list, webhook create, tag search** — List webhooks configured on a Mailchimp audience (list) * **Create landing page, ecommerce store, ecommerce product** — Create a new unpublished, contentless Mailchimp landing page * **Update ecommerce store, template, segment** — Update an existing ecommerce store’s details * **Get ecommerce store, ecommerce product, template** — Get information about a specific ecommerce store * **Delete ecommerce store, template, segment** — Permanently delete an ecommerce store, including all of its products, orders, and customers ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mailercloud MCP connector > Connect to Mailer Cloud MCP. Manage email campaigns, subscriber lists, and automation workflows for your email marketing operations. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mailercloudmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mailercloud MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mailercloudmcp_get_account_overview', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mailercloudmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mailercloud MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mailercloudmcp_get_account_overview", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Contact upsert** — Create a contact if it doesn’t exist, or update it if it does * **Update webhook, template, list** — Update an existing webhook’s configuration * **Webhook toggle** — Enable or disable a webhook * **Send transactional email, test email** — Send a transactional email via MailerCloud Email API * **Campaign schedule, analyze** — Schedule a campaign for sending * **List webhooks, webforms, template categories** — List all webhooks configured in MailerCloud ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mailerlite MCP connector > Connect to MailerLite MCP. Manage email campaigns, subscribers, groups, automations, and forms from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mailerlitemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mailerlite MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mailerlitemcp_get_auth_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mailerlitemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mailerlite MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mailerlitemcp_get_auth_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Lines validate subject** — Validate a list of email subject line candidates against MailerLite best practices * **Content validate email** — Validate email content (subject and body) against MailerLite best practices * **Shops manage ecommerce** — List, fetch, create, update or delete MailerLite e-commerce shops * **Products manage ecommerce, manage ecommerce category** — List, fetch, create, update, delete or bulk-import products within a shop * **Orders manage ecommerce** — List, fetch, create, update, delete or bulk-import orders within a shop * **Customers manage ecommerce** — List, fetch, create, update or delete customers within a shop ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mailgun connector > Connect to Mailgun to send transactional and marketing email, manage domains and DNS/DKIM security, mailing lists, suppressions (bounces, complaints... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Mailgun credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List validate, domain webhooks, account webhooks** — List bulk email-address validation jobs previously submitted on this account, with their status (e.g * **Get validate, domain webhooks, account webhooks** — Get the status and results summary of a single bulk email-address validation job by its list ID, including quantity processed, a pass/fail summary, and (once finished) a download\_url for the full results * **Job validate cancel** — Cancel a bulk email-address validation job by its list ID, stopping further processing * **Address validate** — Validate a single email address using Mailgun’s Validate service: checks syntax, DNS/mailbox deliverability signals, and flags disposable or role-based addresses * **Update domain webhooks, account webhooks, account ip allowlist** — Replace the URL(s) registered for a webhook event type on a domain * **Delete domain webhooks, account webhooks** — Remove all URL(s) registered for a single webhook event type on a domain, effectively disabling callbacks for that event type on this domain ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mailtrap connector > Mailtrap is an email delivery platform for developers that provides transactional and bulk email sending, email sandbox testing, and deliverability tools.... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Mailtrap credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mailtrap' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'mailtrap_get_accounts', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mailtrap" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="mailtrap_get_accounts", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update webhook, sandbox, project** — Update an existing webhook’s URL, active state, payload format, event types, or inbound inbox scope * **Campaign start email** — Start sending a draft campaign immediately * **Send email, bulk email, sandbox** — Send a single transactional email via the Mailtrap Sending API (order confirmations, password resets, notifications) * **Token reset api** — Expire an API token and generate a new token with the same permissions in its place * **Message reply inbound, forward sandbox** — Send a reply to a received inbound email message * **List webhooks, message attachments, inboxes** — List all webhooks configured for the account, including their URL, type, active state, and subscribed event types ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Make MCP connector > Connect to Make (formerly Integromat). Build, run, and manage automation scenarios, data stores, webhooks, and connections across thousands of apps from... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'makemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Make MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'makemcp_custom_apps_connections_fetch', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "makemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Make MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="makemcp_custom_apps_connections_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Interface validate scenario, scenarios** — Use this tool to validate a typed Scenario Interface before applying changes * **List show scenarios, show executions, apps** — Renders an interactive UI in the chat — a searchable, folder-filterable, sortable list of the team’s scenarios showing each scenario’s status, used apps, and usage * **Result show execution** — Renders a scenario execution’s outcome — status, outputs, and consumption — as an interactive widget in the chat, for a past or in-progress run * **Update scenario-custom-properties, custom-apps, tools** — Update scenario custom properties data (scenario-custom-properties): Merge-update custom properties data for a scenario; only the specified items are changed * **Replace scenario-custom-properties, data-store-records** — Replace scenario custom properties data (scenario-custom-properties): Replace all custom properties data for a scenario * **Get scenario-custom-properties, tools, teams** — Get scenario custom properties data (scenario-custom-properties): Get the custom properties data filled in for a scenario ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mem0 MCP connector > Connect to Mem0 MCP. Store, search, and retrieve persistent memory for AI agents and applications using semantic search. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mem0mcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mem0 MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mem0mcp_get_event_status', 25 toolInput: { event_id: 'YOUR_EVENT_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mem0mcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mem0 MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"event_id":"YOUR_EVENT_ID"}, 27 tool_name="mem0mcp_get_event_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update memory** — Overwrite an existing memory’s text * **Search memories** — Run a semantic search over existing memories * **List events, entities** — List memory operation events with optional filters and pagination * **Get memory, memories, event status** — Fetch a single memory by ID * **Delete memory, entities, all memories** — Delete one memory after the user confirms its memory\_id * **Memory add** — Store a new preference, fact, or conversation snippet ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Memberstack MCP connector > Connect to Memberstack MCP. Manage members, plans, form submissions, and permissions for your membership-based application. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'memberstackmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Memberstack MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'memberstackmcp_currentapp', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "memberstackmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Memberstack MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="memberstackmcp_currentapp", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Updaterestrictedurlgroup records** — Updates configuration of an existing gated content group * **Updaterestrictedurl records** — Updates URL path or filter behavior for a gated page * **Updateprice records** — Updates an existing price configuration and syncs with Stripe * **Updateplanlogic records** — Configures automation rules for plan additions, removals, and transitions * **Updateplan records** — Updates configuration of an existing subscription plan * **Updatemembernote records** — Creates or updates internal admin notes for a member ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mem MCP connector > A hosted MCP server that gives AI tools secure access to your Mem notes and collections — enabling AI agents to read, create, search, and organize notes... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'memmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mem MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'memmcp_list_collections', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "memmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mem MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="memmcp_list_collections", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update note, collection** — Submit a complete markdown body for a note and the exact `version` being updated * **Note trash, restore, move** — Soft-delete a note by moving it to trash * **At set note created** — Set a note’s visible creation timestamp without changing its content * **Search notes, collections, extended** — Search notes using a required free-text query and structured filters * **Collection remove note from, add note to** — Remove a note from a collection while keeping both resources * **Read attachment** — Read structured content for a single attachment by kind and ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mercury MCP connector > Connect to Mercury. Access accounts, transactions, recipients, invoices, treasury, webhooks, and approval requests for startup banking workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mercurymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mercury MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mercurymcp_getaccounts', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mercurymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mercury MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mercurymcp_getaccounts", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Listrecipientinvites records** — Retrieve a paginated list of all recipient invites for your organization * **Listmerchants records** — Retrieve a paginated list of priority merchants that can be used for spend controls like merchant locking * **Listcards records** — Retrieve a paginated list of cards * **Getrecipientinvite records** — Retrieve details of a specific recipient invite by ID * **Getcard records** — Retrieve details of a specific card by its ID * **Listtransactions records** — Retrieve a paginated list of transactions across all accounts with advanced filtering ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Metaview MCP connector > Metaview is an agentic recruiting platform that automates end-to-end hiring workflows — from candidate sourcing and outreach to interview note-taking and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'metaviewmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Metaview MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'metaviewmcp_find_candidate_in_sequences', 25 toolInput: { rationale: 'YOUR_RATIONALE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "metaviewmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Metaview MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"rationale":"YOUR_RATIONALE"}, 27 tool_name="metaviewmcp_find_candidate_in_sequences", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Contacts enrich candidate** — Enrich email addresses or phone numbers for one or more candidates * **Update screen plan, application review icp** — Replace a screen’s interview plan and publish it immediately as the next ACTIVE version * **Icp restore application review** — Restore a previous Application Review ICP version: the restored content becomes a new latest version, is approved on the spot, and a rerank starts against it immediately — there is no separate confirmation step * **Ats post sourcing candidates to** — Post candidates from a sourcing search to the workspace’s connected ATS, creating each candidate there if they don’t already exist and adding an application to the given job * **List screens, screen candidates, ats stages** — List the Screening screens you can access, with summary information per screen: ATS job posts, run state, active plan version, whether the draft holds unpublished edits, and candidate roster by stage * **Feedback give application review candidate, give sourcing** — Record a REJECT or PROGRESS decision on one or more admitted candidates in an Application Review, optionally with free-text feedback ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Metricool MCP connector > Metricool is a social media analytics and scheduling platform for managing, analyzing, and scheduling content across Instagram, Twitter/X, Facebook... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'metricoolmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Metricool MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'metricoolmcp_getanalyticsavailablemetrics', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "metricoolmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Metricool MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="metricoolmcp_getanalyticsavailablemetrics", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sendscheduledpostforreview records** — Send an already-scheduled post to review (approval flow) in Metricool * **Createscheduledpostforreview records** — Schedule a new post and send it to review (approval flow) in Metricool, replicating the web “Send for review” action * **Updatescheduledpost records** — Update a scheduled post in Metricool * **Getscheduledposts records** — Get the list of scheduled posts for a specific Metricool brand * **Getbrandsettings records** — Get the list of brands from your Metricool account * **Getbesttimetopostbynetwork records** — Get the best time to post for a specific social network on a Metricool account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Microsoft 365 connector > Connect to Microsoft 365. Unified access to Outlook, Excel, Word, OneNote, OneDrive, SharePoint, and Teams through Microsoft Graph API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Microsoft 365 credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'microsoft365' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Microsoft 365:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'microsoft365_outlook_mailbox_settings_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "microsoft365" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Microsoft 365:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="microsoft365_outlook_mailbox_settings_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update teams, outlook** — Update the properties of a group chat, such as renaming its topic * **Member teams remove chat, teams add chat, teams remove team** — Remove a member from a Microsoft Teams group chat * **Tab teams remove channel** — Remove (unpin) a tab from a Microsoft Teams channel * **List teams** — List the transcripts generated for a Microsoft Teams online meeting * **Get teams, sharepoint** — Get the presence information (available, busy, away, etc.) for multiple users in a single request * **Delete teams, outlook permanently, outlook** — Soft-delete a message in a Microsoft Teams chat ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Microsoft Excel connector > Connect to Microsoft Excel. Access, read, and modify spreadsheets stored in OneDrive or SharePoint through Microsoft Graph API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Microsoft Excel credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'microsoftexcel' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Microsoft Excel:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'microsoftexcel_list_comments', 25 toolInput: { item_id: 'YOUR_ITEM_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "microsoftexcel" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Microsoft Excel:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"item_id":"YOUR_ITEM_ID"}, 27 tool_name="microsoftexcel_list_comments", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Data set chart** — Repoint an existing chart at a new source data range and/or seriesBy setting * **Table refresh pivot, sort, filter** — Refresh a single PivotTable’s data from its source range, picking up any changes made to the underlying data since it was last refreshed * **Tables refresh all pivot** — Refresh every PivotTable on a worksheet in one call, picking up any changes made to their underlying source data since they were last refreshed * **List pivot tables, worksheets, tables** — List all PivotTables on a worksheet in an Excel workbook stored in OneDrive * **Get used range, named item, chart image** — Retrieve the smallest range that contains any data or formatting on an Excel worksheet stored in OneDrive, without needing to already know the address * **Delete named item, worksheet, table row** — Delete a named item (named range or named formula) definition from an Excel workbook stored in OneDrive ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Teams connector > Connect to Microsoft Teams. Manage messages, channels, meetings, and team collaboration 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Teams credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'microsoftteams' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Teams:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'microsoftteams_list_all_teams', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "microsoftteams" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Teams:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="microsoftteams_list_all_teams", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update chat message, chat, team member** — Update the body content of an existing Microsoft Teams chat message * **Message unreact to channel, restore channel, react to channel** — Remove a reaction previously set by the signed-in user from a Microsoft Teams channel message * **App uninstall, install** — Uninstall an app from a Microsoft Teams team * **Team unarchive, clone, archive** — Restore an archived Microsoft Teams team, allowing members to send messages and edit the team again * **Channel unarchive, archive** — Restore an archived channel in a Microsoft Teams team, allowing members to send messages and edit the channel again * **Member remove chat, remove channel, add chat** — Remove a member from a Microsoft Teams chat ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Microsoft Word connector > Connect to Microsoft Word. Authenticate with your Microsoft account to create, read, and edit Word documents stored in OneDrive or SharePoint through... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Microsoft Word credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'microsoftword' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Microsoft Word:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'microsoftword_get_document', 25 toolInput: { item_id: 'YOUR_ITEM_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "microsoftword" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Microsoft Word:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"item_id":"YOUR_ITEM_ID"}, 27 tool_name="microsoftword_get_document", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update document content** — Overwrite the content of an existing Word document (.docx) in OneDrive by initiating an upload session against its item ID * **Search documents** — Search the signed-in user’s personal OneDrive for items matching a query string, searching across file names and content * **Document move, copy** — Move a Word document (.docx) to a different OneDrive folder, rename it, or both, by PATCHing its parentReference and/or name * **List documents, document versions** — List the children of a OneDrive folder, intended for finding Word (.docx) files * **Get document** — Retrieve metadata for a Word document (.docx) in OneDrive by item ID * **Delete document** — Delete a Word document (.docx) from OneDrive by item ID ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mini Course Generator MCP connector > Mini Course Generator is a platform for creating and publishing short, focused online mini-courses. It enables creators to build bite-sized educational... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'minicoursegeneratormcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mini Course Generator MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'minicoursegeneratormcp_course_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "minicoursegeneratormcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mini Course Generator MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="minicoursegeneratormcp_course_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Replace scorm** — Correct or update an already-hosted SCORM activity **in place**, keeping the same `packageId` * **Delete scorm, section, module** — Delete a hosted SCORM package * **Unpublish module, lesson** — Move a Module back to draft * **Theme module** — Set how the learner sees a Module: page layout, typography and colours * **Publish module, lesson** — Publish a Module: it and every Lesson in it become visible to learners, and its previewUrl starts working * **Move module, lesson** — Reorder a Module within its Course by setting its zero-based position (lower comes first) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mintlify MCP connector > Connect to Mintlify MCP. Read and edit documentation pages, manage navigation nodes, search content, and publish changes via pull requests from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mintlifymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mintlify MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mintlifymcp_get_session_state', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mintlifymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mintlify MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mintlifymcp_get_session_state", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search code operations** — Lexical (BM25) search over the Admin MCP code-mode SDK to find the right SDK method for a task before writing an execute\_code script * **List deployments, nodes, branches** — List the deployments this connection is authorized for, returning each subdomain and name * **Execute code** — Run TypeScript/JavaScript against the Admin MCP dashboard SDK inside a sandboxed Cloudflare isolate to call workflows, deployment, billing, or analytics APIs * **Page write, edit** — Fully overwrite a page’s MDX content on the current branch by path * **Update node, config** — Update a navigation node’s properties in place by node ID, including page frontmatter fields like title, description, icon, or tag * **Save records** — Flush branch changes to git by opening a pull request or committing directly, depending on the selected mode ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Miro connector > Miro is a visual collaboration platform for teams. Manage boards, sticky notes, shapes, cards, frames, connectors, images, and tags using the Miro REST... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Miro credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'miro' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Miro:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'miro_boards_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "miro" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Miro:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="miro_boards_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update project, project settings, project member** — Updates a project’s (space’s) name * **Get project settings, project member, doc item** — Retrieves the sharing and access settings for a project * **Lookup group items** — Given the ID of any item that belongs to a group, returns all items that are part of that same group on the board * **Delete doc item, team, item** — Deletes a doc format item from a Miro board * **Create doc item, shape, embed** — Creates a doc format item (a native markdown text block) on a Miro board * **List board members, tags, mindmap nodes** — Returns a list of members on a Miro board ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Miro MCP connector > Connect to Miro MCP to create and manage boards, frames, sticky notes, shapes, diagrams, and comments directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'miromcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Miro MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'miromcp_space_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "miromcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Miro MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="miromcp_space_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update table, space, space role** — Update a Miro table widget’s view: switch it to a grid table, timeline, or kanban board * **Get table, diagram, canvas** — Get the history of a row’s Latest Update field * **Share space, board** — Grant a user or user group access to a space with a specific role * **List space** — List the direct children of a space or section, one level deep * **Create space, section, diagram** — Create a new Miro space * **Delete section, code widget** — Delete a section ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mixmax MCP connector > Connect to Mixmax MCP. Manage email sequences, templates, contacts, and engagement analytics from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mixmaxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mixmax MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mixmaxmcp_mixmax_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mixmaxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mixmax MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mixmaxmcp_mixmax_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sequences records** — Query, inspect, and create Mixmax email sequences * **Info mixmax** — Retrieve general information about the Mixmax account and configuration * **Meetings records** — Query Mixmax meetings and calendar data ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mixpanel Analytics connector > Connect to Mixpanel's Query API, Lexicon Schemas, and Warehouse Connectors to run segmentation, funnel, retention, and Insights reports, execute custom... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Mixpanel Analytics credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List feature flags, annotations, annotation tags** — List every feature flag/experiment defined in a Mixpanel project workspace, including each flag’s variants, rollout rules, and status * **Get feature flag variant assignments, feature flag, feature flag definitions** — Evaluate all enabled feature flags and experiments for a given user/context, returning the variant each flag assigns them * **Update feature flag, annotation, warehouse import** — Replace an existing feature flag’s full configuration by id — this is a full update, not a partial patch, so provide the complete desired ‘name’, ‘key’, ‘tags’, ‘context’, ‘serving\_method’, and ‘ruleset’ (not just the fields you’re changing) * **Delete feature flag, annotation, warehouse import** — Permanently delete a feature flag from a Mixpanel project workspace * **Create feature flag, annotation tag, annotation** — Create a new feature flag/experiment definition in a Mixpanel project workspace, including its variants and rollout rules * **Run warehouse import** — Manually trigger an immediate sync run for a warehouse import, outside its configured schedule (‘run\_every’) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mixpanel Compliance connector > Connect to Mixpanel's GDPR/CCPA compliance API to submit and track end-user data deletion (right to erasure) and data retrieval (subject access) requests.... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Mixpanel Compliance credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mixpanelcompliance' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'mixpanelcompliance_gdpr_deletion_status', 19 toolInput: { tracking_id: 'YOUR_TRACKING_ID', project_token: 'YOUR_PROJECT_TOKEN' }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mixpanelcompliance" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"tracking_id":"YOUR_TRACKING_ID","project_token":"YOUR_PROJECT_TOKEN"}, 19 tool_name="mixpanelcompliance_gdpr_deletion_status", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Status gdpr retrieval, gdpr deletion** — Check the status of a GDPR/CCPA data retrieval (Subject Access Request) previously created with ‘mixpanelcompliance\_gdpr\_retrieval\_create’ * **Create gdpr retrieval, gdpr deletion** — Create a GDPR or CCPA Subject Access Request (SAR) for one or more Mixpanel distinct\_ids * **Cancel gdpr deletion** — Cancel a pending GDPR/CCPA data deletion request before Mixpanel begins permanently erasing the data ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mixpanel Ingestion connector > Connect to Mixpanel's Ingestion API to track events, manage user and group profiles, resolve identities, replace lookup tables, and evaluate feature... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Mixpanel Ingestion credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Event track** — Send a single event to Mixpanel via the classic /track endpoint, authenticated with your Mixpanel Project Token (not your Service Account) * **Unset profile, group** — Permanently remove one or more named properties (and their values) from a Mixpanel user profile via Engage $unset * **Union profile, group** — Add values to a list-valued property on a Mixpanel user profile via Engage $union, ensuring each value only appears once in the resulting list * **Once profile set, group set** — Set properties on a Mixpanel user profile via Engage $set\_once, but only if they are not already set — existing values are never overwritten * **Set profile, group** — Set (overwrite) properties on a Mixpanel user profile via Engage $set * **Remove profile, group** — Remove a specific value from a list-valued property on a Mixpanel user profile via Engage $remove ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mobbin MCP connector > Connect to Mobbin's MCP server to search real-world UI and UX design references from mobile apps, web apps, and websites using natural language. Returns... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mobbinmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mobbin MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mobbinmcp_search_sections', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mobbinmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mobbin MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="mobbinmcp_search_sections", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search sections, screens, flows** — Search Mobbin for website sections (e.g ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Momentum connector > Connect to Momentum, the AI-powered revenue intelligence platform. Retrieve meetings with attendee and transcript details, ingest and remap meetings, run... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'momentum' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'momentum_list_signal_definitions', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "momentum" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="momentum_list_signal_definitions", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Meeting remap, ingest** — Associate a meeting with new Salesforce objects (account, opportunity, and/or lead) and optionally trigger call summary generation and AI signals * **List users, signal v2 executions, signal prompts** — Retrieve a paginated list of users in your Momentum organization, including their profile, role, license status, and Salesforce/Google Calendar authentication status ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Monday.com connector > Connect to Monday.com. Manage boards, tasks, workflows, teams, and project collaboration 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Monday.com credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'monday' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Monday:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first API call through the proxy 21 const result = await actions.request({ 22 connectionName: connector, 23 identifier, 24 path: '/v2', 25 method: 'POST', 26 body: JSON.stringify({ query: '{ boards (limit: 5) { id name } }' }), 27 }) 28 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 import json 3 from scalekit.client import ScalekitClient 4 from dotenv import load_dotenv 5 load_dotenv() 6 7 scalekit_client = ScalekitClient( 8 env_url=os.getenv("SCALEKIT_ENV_URL"), 9 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 10 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 11 ) 12 actions = scalekit_client.actions 13 14 connection_name = "monday" 15 identifier = "user_123" 16 17 # Generate an authorization link for the user 18 link_response = actions.get_authorization_link( 19 connection_name=connection_name, 20 identifier=identifier, 21 ) 22 print("Authorize Monday:", link_response.link) 23 input("Press Enter after authorizing...") 24 25 # Make your first API call through the proxy 26 result = actions.request( 27 connection_name=connection_name, 28 identifier=identifier, 29 path="/v2", 30 method="POST", 31 body=json.dumps({"query": "{ boards (limit: 5) { id name } }"}), 32 ) 33 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Manage boards** — create, update, archive, duplicate, and delete boards across workspaces * **Manage items** — create, update, move, duplicate, archive, and delete items (rows) on any board * **Update column values** — set single or multiple column values including status, date, people, and custom types * **Manage groups** — create, rename, reorder, duplicate, archive, and delete groups within a board * **Post updates** — add, edit, and delete comments and activity updates on items * **Manage structure** — create and delete columns, manage subitems, webhooks, workspaces, teams, and tags ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most Monday.com tools require one or more resource IDs. Run list/read tools first to discover real IDs — never guess them. | Resource | Tool to get ID | Field in response | | ------------ | -------------------------------------------- | ----------------------------------------------------- | | Board ID | `monday_boards_list` | `data.boards[].id` | | Item ID | `monday_items_list` (requires `board_id`) | `data.boards[].items_page.items[].id` | | Group ID | `monday_items_list` | `data.boards[].items_page.items[].group.id` | | Column ID | `monday_items_list` | `data.boards[].items_page.items[].column_values[].id` | | User ID | `monday_users_list` or `monday_me_get` | `data.users[].id` / `data.me.id` | | Workspace ID | `monday_workspaces_list` | `data.workspaces[].id` | | Update ID | `monday_updates_list` | `data.updates[].id` | | Tag ID | `monday_tags_list` | `data.tags[].id` | | Team ID | `monday_teams_list` | `data.teams[].id` | | Webhook ID | `monday_webhooks_list` (requires `board_id`) | `data.webhooks[].id` | | Doc ID | `monday_docs_list` | `data.docs[].id` | | Subitem ID | `monday_subitem_create` response | `data.create_subitem.id` | ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Monday MCP connector > Connect to the monday.com MCP server to manage boards, items, columns, docs, and workflows directly from your AI agents. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Monday MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mondaymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Monday MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mondaymcp_search', 25 toolInput: { searchType: 'YOUR_SEARCHTYPE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mondaymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Monday MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"searchType":"YOUR_SEARCHTYPE"}, 27 tool_name="mondaymcp_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Vibeupdate records** — Sends a follow-up message to modify an existing app * **Vibepublication records** — Manage the publication state of a Vibe app on the caller account * **Vibelist records** — List Vibe apps owned by the authenticated user * **Vibeget records** — Fetch a Vibe app by id * **Vibedelete records** — Delete a Vibe app and its associated assets * **Vibecreate records** — Creates a new Vibe app from a natural-language prompt ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Get items from a board Use `mondaymcp_get_board_items_page` to fetch items from a monday.com board. You need the board’s numeric ID, which you can find in the board URL (`https://mycompany.monday.com/boards/`). * Node.js ```typescript 1 const items = await actions.executeTool({ 2 connectionName: 'mondaymcp', 3 identifier: 'user_123', 4 toolName: 'mondaymcp_get_board_items_page', 5 toolInput: { 6 boardId: '1234567890', 7 limit: 50, 8 }, 9 }); 10 console.log(items); ``` * Python ```python 1 items = actions.execute_tool( 2 connection_name="mondaymcp", 3 identifier="user_123", 4 tool_name="mondaymcp_get_board_items_page", 5 tool_input={ 6 "boardId": "1234567890", 7 "limit": 50, 8 }, 9 ) 10 print(items) ``` ### Create an item and add an update Use `mondaymcp_create_item` to add a new item to a board, then `mondaymcp_create_update` to post a comment or status update on it. * Node.js ```typescript 1 // Step 1 — create the item 2 const newItem = await actions.executeTool({ 3 connectionName: 'mondaymcp', 4 identifier: 'user_123', 5 toolName: 'mondaymcp_create_item', 6 toolInput: { 7 boardId: '1234567890', 8 itemName: 'Fix login bug', 9 groupId: 'topics', 10 }, 11 }); 12 const itemId = newItem.id; 13 14 // Step 2 — post an update on the item 15 await actions.executeTool({ 16 connectionName: 'mondaymcp', 17 identifier: 'user_123', 18 toolName: 'mondaymcp_create_update', 19 toolInput: { 20 itemId, 21 body: 'Assigned to the auth team. Expected fix in next sprint.', 22 }, 23 }); ``` * Python ```python 1 # Step 1 — create the item 2 new_item = actions.execute_tool( 3 connection_name="mondaymcp", 4 identifier="user_123", 5 tool_name="mondaymcp_create_item", 6 tool_input={ 7 "boardId": "1234567890", 8 "itemName": "Fix login bug", 9 "groupId": "topics", 10 }, 11 ) 12 item_id = new_item["id"] 13 14 # Step 2 — post an update on the item 15 actions.execute_tool( 16 connection_name="mondaymcp", 17 identifier="user_123", 18 tool_name="mondaymcp_create_update", 19 tool_input={ 20 "itemId": item_id, 21 "body": "Assigned to the auth team. Expected fix in next sprint.", 22 }, 23 ) ``` ### Update column values on an item Use `mondaymcp_change_item_column_values` to set structured column data — such as status, date, or assignee — on an existing item. * Node.js ```typescript 1 await actions.executeTool({ 2 connectionName: 'mondaymcp', 3 identifier: 'user_123', 4 toolName: 'mondaymcp_change_item_column_values', 5 toolInput: { 6 boardId: '1234567890', 7 itemId: '9876543210', 8 // Column values are JSON-encoded per the monday.com column type 9 columnValues: JSON.stringify({ 10 status: { label: 'In Progress' }, 11 date4: { date: '2025-08-01' }, 12 }), 13 }, 14 }); ``` * Python ```python 1 import json 2 3 actions.execute_tool( 4 connection_name="mondaymcp", 5 identifier="user_123", 6 tool_name="mondaymcp_change_item_column_values", 7 tool_input={ 8 "boardId": "1234567890", 9 "itemId": "9876543210", 10 # Column values are JSON-encoded per the monday.com column type 11 "columnValues": json.dumps({ 12 "status": {"label": "In Progress"}, 13 "date4": {"date": "2025-08-01"}, 14 }), 15 }, 16 ) ``` ### Search across monday.com Use `mondaymcp_search` to find items, boards, docs, or users by keyword. * Node.js ```typescript 1 const results = await actions.executeTool({ 2 connectionName: 'mondaymcp', 3 identifier: 'user_123', 4 toolName: 'mondaymcp_search', 5 toolInput: { 6 query: 'Q3 roadmap', 7 searchType: 'boards', 8 }, 9 }); 10 console.log(results); ``` * Python ```python 1 results = actions.execute_tool( 2 connection_name="mondaymcp", 3 identifier="user_123", 4 tool_name="mondaymcp_search", 5 tool_input={ 6 "query": "Q3 roadmap", 7 "searchType": "boards", 8 }, 9 ) 10 print(results) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # MotherDuck MCP connector > Connect to MotherDuck MCP. Query and analyze DuckDB databases, explore schemas, create visualizations, and automate data workflows from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'motherduckmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize MotherDuck MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'motherduckmcp_get_flight_guide', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "motherduckmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize MotherDuck MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="motherduckmcp_get_flight_guide", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update guide metadata, guide, flight** — Change a guide’s title, description, or topic without appending a content version * **Access set guide** — Set a guide’s visibility to ‘user’ (private to the owner) or ‘organization’ (visible to the whole org) * **List views, macros, guides** — List all views in a MotherDuck database, with their schema, comment, and column count * **Get query guide, guide, flight logs** — Call this before writing SQL to answer a data question * **Content edit guide, edit dive** — Edit a guide’s markdown body by applying one or more text replacements, then save as a new version * **Delete guide, flight, dive** — Soft-delete a guide while preserving its version history ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Motion MCP connector > Connect to Motion MCP. Manage tasks, projects, workspaces, and schedules in the Motion AI-powered project management platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'motionmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Motion MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'motionmcp_get_auth_context', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "motionmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Motion MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="motionmcp_get_auth_context", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Feedback submit** — Submit feedback about this Motion MCP server to the Motion product team * **Search brands** — Search for brands by name or domain query * **Get workspace competitors, workspace brand, reports** — List competitor brands the workspace is tracking, with optional filtering by specific brand IDs ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # MT Newswires MCP connector > Connect to the MT Newswires MCP server on viaNexus to search and retrieve real-time, low-latency financial news across equities, fixed income... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'mtnewswiresmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize MT Newswires MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'mtnewswiresmcp_get_rules', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "mtnewswiresmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize MT Newswires MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="mtnewswiresmcp_get_rules", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search records** — Search the available viaNexus / MT Newswires datasets * **Get rules** — Get all alert rules associated with the user * **Fetch records** — Retrieve rows of data from a viaNexus / MT Newswires dataset * **Delete rule** — Delete an alert rule by its id * **Date current** — Provides the current date * **Create rule** — Create an alert rule for one or more datasets that sends an email when the conditions are met ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Mux MCP connector > Mux is a video infrastructure platform for developers, providing APIs for video hosting, on-demand streaming, live streaming, and playback with analytics... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'muxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Mux MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'muxmcp_search_docs', 25 toolInput: { query: 'YOUR_QUERY', language: 'YOUR_LANGUAGE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "muxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Mux MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY","language":"YOUR_LANGUAGE"}, 27 tool_name="muxmcp_search_docs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search docs** — Search SDK documentation to find methods, parameters, and usage examples for interacting with the API * **Execute records** — Runs JavaScript code to interact with the Mux API ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Neon MCP connector > Connect to Neon MCP. Manage Neon serverless Postgres databases, projects, branches, and queries from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'neonmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Neon MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'neonmcp_list_branch_computes', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "neonmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Neon MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="neonmcp_list_branch_computes", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Query logs, prepare, complete** — Query logs emitted by Neon serverless functions and other services (structured filters or raw LogQL), correlated by trace ID and time window * **List log fields, log field values, slow queries** — List the log fields whose values list\_log\_field\_values can enumerate for a branch (e.g * **Database inspect** — Run a predefined, read-only Postgres diagnostic check (table sizes, unused indexes, locks, bloat, etc.) against a Neon branch * **Search records** — Search across all organizations, projects, and branches by keyword, returning matching items with IDs and URLs * **Run sql transaction, sql** — Execute multiple SQL statements as a single transaction against a Neon database * **Parent reset from** — Reset a branch to its parent branch state, discarding all changes made on the branch ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Netlify MCP connector > Build, deploy, and manage Netlify projects — sites, functions, environment variables, forms, blobs, and edge functions — from AI agents via the Netlify... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'netlifymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Netlify MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'netlifymcp_get_netlify_coding_context', 25 toolInput: { creationType: 'YOUR_CREATIONTYPE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "netlifymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Netlify MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"creationType":"YOUR_CREATIONTYPE"}, 27 tool_name="netlifymcp_get_netlify_coding_context", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Reader netlify user services, netlify team services, netlify project services** — Read Netlify user information * **Updater netlify project services, netlify extension services, netlify deploy services** — Write operations for Netlify projects/sites * **Get netlify coding context** — ALWAYS call when writing code ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Nimble MCP connector > Connect to Nimble MCP. Search the web across multiple engines, extract content from any URL, crawl websites at scale, discover all URLs on a site, and run... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Nimble MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'nimblemcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'nimblemcp_nimble_agent_templates_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "nimblemcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="nimblemcp_nimble_agent_templates_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update nimble extract templates, nimble agents** — Create a refinement generation that starts from an existing extract template * **Run nimble extract templates, nimble agents** — Start an asynchronous extract template run * **List nimble extract templates, nimble agents runs, nimble agent templates** — Browse the catalog of extract templates * **Get nimble extract templates, nimble agent templates, nimble agents** — Get full details of a specific extract template including its input/output schema * **Status nimble extract templates generation, nimble crawl, nimble agents** — Check the current status of an extract template generation * **Generate nimble extract templates, nimble agents** — Kick off generation of a new custom extract template ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # NocoDB MCP connector > Connect to NocoDB MCP. Create and manage databases, tables, records, views, and fields from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'nocodbmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize NocoDB MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'nocodbmcp_getbaseinfo', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "nocodbmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize NocoDB MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="nocodbmcp_getbaseinfo", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Updaterecords records** — Update records in a table * **Readattachment records** — Read attachments in a record * **Queryrecords records** — Query Records from a Table * **Gettableslist records** — List tables accessible by user * **Gettableschema records** — Get the table schema including fields and views information * **Getrecord records** — Fetch a record by ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Notion connector > Connect to Notion workspace. Create, edit pages, manage databases, and collaborate on content 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Notion credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'notion' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Notion:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'notion_custom_emojis_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "notion" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Notion:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="notion_custom_emojis_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read pages and databases** — retrieve page content and query database entries * **Create pages** — add new pages and database rows with full content * **Update content** — edit existing page blocks, properties, and database fields * **Search** — find pages and databases across the user’s Notion workspace ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Notion MCP connector > Connect to Notion MCP. Create and update pages, databases, comments, and views from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'notionmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Notion MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'notionmcp_notion-create-attachment', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "notionmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Notion MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="notionmcp_notion-create-attachment", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Notion-update-folder records** — Update an existing Notion Folder: add uploaded files, remove files by their exact fetched URLs, or add a new nested subfolder * **Notion-search-agents records** — Search agents by name or description, or browse the current user’s favorite agents and the workspace’s newest agents * **Notion-list-shared-pages records** — List pages and databases in the current user’s Shared sidebar section * **Notion-list-recent-pages records** — List pages and databases the current user recently viewed, ranked by recency and visit frequency * **Notion-list-private-pages records** — List the current user’s top-level pages and databases in their Private sidebar section * **Notion-list-favorite-pages records** — List the current user’s favorite pages and databases in sidebar order ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # OneDrive connector > Connect to OneDrive. Manage files, folders, and cloud storage with Microsoft OneDrive 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your OneDrive credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'onedrive' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize OneDrive:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'onedrive_get_drive', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "onedrive" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize OneDrive:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="onedrive_get_drive", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Version restore item** — Restore a previous version of a OneDrive file, making it the current version * **Item preview, unfollow drive, restore drive** — Get a short-lived, embeddable preview URL for a OneDrive file so it can be viewed in a browser (e.g * **List items by path, delta, versions** — List the children (files and folders) of a folder in the signed-in user’s personal OneDrive using its human-readable folder path instead of an item ID * **Get special folder, permission, item by path** — Retrieve metadata for a well-known special folder in the signed-in user’s OneDrive by its alias name, without needing to know its item ID * **Drive download file in, copy item in** — Download the binary content of a file in a specific drive (e.g * **File upload large, download, checkout** — Create a resumable upload session for uploading large files (greater than 4 MB) to OneDrive ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # OneNote connector > Connect to Microsoft OneNote. Access, create, and manage notebooks, sections, and pages stored in OneDrive or SharePoint through Microsoft Graph API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your OneNote credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'onenote' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize OneNote:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'onenote_list_notebooks', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "onenote" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize OneNote:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="onenote_list_notebooks", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update page content** — Apply a single patchContentCommand to an existing OneNote page’s content, per the Graph OneNote page-update semantics (a JSON array containing one command object with target/action/position/content) * **Search pages** — Search all of the signed-in user’s OneNote pages (across every notebook and section) for pages whose title contains the given text * **List sections, section groups, pages** — List the OneNote sections (onenoteSection objects) inside a specific notebook * **Get page content** — Retrieve the full HTML content of a OneNote page by page ID * **Delete page** — Permanently delete a OneNote page by page ID * **Create section group, section, page** — Create a new section group directly inside the specified notebook ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Onepage MCP connector > Onepage is a website builder platform. The MCP connector lets Claude create, edit, and manage Onepage websites and pages on behalf of the user. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'onepagemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Onepage MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'onepagemcp_list_sites', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "onepagemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Onepage MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="onepagemcp_list_sites", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Section patch, rename, edit** — Apply a sparse DSL patch to an existing native no-code section, using a revision read from get\_section in patch mode * **Files write siteui, write, edit siteui** — Write (create or overwrite) multiple source files in a @siteui shared package * **File write, edit** — Write (create or overwrite) a single source file in a vibe section’s React app * **Whoami records** — Get the authenticated Onepage account identity (email, name, language, role) * **Media upload** — Upload a media file (image, video, document) to the site’s media library * **Update site settings, page settings, crm form** — Patch site-level settings ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # OpenRouter MCP connector > Connect to OpenRouter's MCP server to access unified LLM routing, model discovery, and generation tools directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'openroutermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize OpenRouter MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'openroutermcp_get_credits', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "openroutermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize OpenRouter MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="openroutermcp_get_credits", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Audio transcribe** — Transcribe speech from an audio file to text * **Eval spawn ori** — Get the instructions for running a model eval with Ori, then follow them * **List presets, task classifications, providers** — List the caller’s saved presets (named bundles of model, system prompt, and sampling config created in the OpenRouter dashboard), ordered by most recently updated * **Harness install ori** — Get the instructions for installing and using Ori Harness, then follow them * **Get preset, endpoint uptime history, model** — Get one saved preset by slug, including its designated version’s config bundle (model, system prompt, temperature, and other sampling parameters), to inspect or reuse that configuration in a request * **Speech generate** — Synthesize speech from text and return it inline as an audio content block (clients that can play audio render it; not all MCP clients can) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # OtterAI MCP connector > Connect to OtterAI MCP. Search meeting recordings, fetch full transcripts, and retrieve user account info from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'otteraimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize OtterAI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'otteraimcp_otter_get_user_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "otteraimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize OtterAI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="otteraimcp_otter_get_user_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search otter** — Search meetings across platforms by date, attendee, topic, keyword, or title * **Get otter** — Return the name and email of the currently authenticated OtterAI user * **Fetch otter** — Retrieve the full transcript and metadata for a single OtterAI meeting by its ID, returned by otter\_search ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Outlook connector > Connect to Microsoft Outlook. Manage emails, calendar events, contacts, and tasks 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Outlook credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'outlook' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Outlook:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'outlook_list_calendar_events', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "outlook" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Outlook:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="outlook_list_calendar_events", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update calendar, shared calendar event, focused inbox override** — Rename or recolor an existing calendar * **Send draft message, message from shared mailbox, message** — Send an existing draft message, such as one created with Create Draft Message * **Message reply all, forward, copy** — Immediately reply to the sender and all recipients of a message, without creating a draft first * **Delete permanently, shared calendar event, message attachment** — Permanently delete a message, bypassing the Deleted Items folder entirely * **Folder move mail, copy mail** — Move a mail folder, along with its contents and any child folders, under another folder * **List event attachments, child folders, shared todo tasks** — List all attachments on a specific calendar event ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Outreach connector > Connect with Outreach to manage prospects, accounts, sequences, emails, calls, and sales engagement workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'outreach' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Outreach:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'outreach_account_notes_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "outreach" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Outreach:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="outreach_account_notes_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update webhook, snippet, sequence step** — Update an existing webhook’s URL, subscribed event type, resource type, or signing secret in Outreach * **Reschedule task** — Reschedule a task’s due date in Outreach * **List snippets, prospect notes, opportunity prospect roles** — List reusable email snippets in Outreach, with optional filtering by name, share type, or owner, and pagination * **Get snippet, email address, sequences** — Get a single reusable email snippet from Outreach by ID * **Delete snippet, prospect note, email address** — Permanently delete a reusable email snippet from Outreach by ID * **Create snippet, sequence step, prospect note** — Create a new reusable email snippet in Outreach ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # PagerDuty connector > Connect to PagerDuty to manage incidents, services, users, teams, escalation policies, schedules, and on-call rotations. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pagerduty' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize PagerDuty:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pagerduty_abilities_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pagerduty" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize PagerDuty:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pagerduty_abilities_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get vendor, user me, incident alert** — Get details of a specific PagerDuty vendor (integration type) by its ID * **Remove team user, team escalation policy** — Remove a user from a PagerDuty team * **Add team user, team escalation policy** — Add a user to a PagerDuty team with a given role * **List team members, tags, schedule users** — List the members of a PagerDuty team * **Create tag, schedule override, incident responder request** — Create a new tag, which can then be assigned to escalation policies, teams, or users to filter and group them * **Delete schedule override, user, schedule** — Delete an on-call override from a PagerDuty schedule ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pandadoc MCP connector > Connect to PandaDoc MCP. Create, send, and manage documents, templates, and e-signatures directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pandadocmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Pandadoc MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pandadocmcp_documents_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pandadocmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Pandadoc MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pandadocmcp_documents_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create documents** — build a document from a PandaDoc template, from markdown content, or from a PDF/DOCX file URL * **Send for signature** — send a draft to its recipients with a custom subject and message, control email notifications, and set forwarding and approval options * **Manage recipients** — add CC recipients, edit a recipient’s details, reassign a signer to another contact, or remove a recipient * **Track status and history** — check document status, retrieve the full audit trail, and manually mark a document Completed, Paid, Expired, or Declined * **Find and read documents** — list with status, folder, tag, sorting and date-range filters, full-text search, and pull content, details, summaries, or metadata (single or batched across up to 40 documents) * **Work with templates** — list templates, inspect a template’s roles, fields, tokens and pricing tables, or create a new template from a PDF URL ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Parallel AI Task MCP connector > Connect to Parallel AI Task MCP to run deep research tasks and task groups directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Parallel AI Task MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'parallelaitaskmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'parallelaitaskmcp_get_result_markdown', 19 toolInput: { taskRunOrGroupId: 'YOUR_TASKRUNORGROUPID' }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "parallelaitaskmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"taskRunOrGroupId":"YOUR_TASKRUNORGROUPID"}, 19 tool_name="parallelaitaskmcp_get_result_markdown", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get result markdown, status** — Fetch the final results of a completed Deep Research or Task Group run as Markdown * **Create task group, deep research** — Batch data enrichment tool ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pendo MCP connector > Connect to Pendo MCP to access product analytics, user guidance, and engagement data directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pendomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Pendo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pendomcp_listallapplications', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pendomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Pendo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pendomcp_listallapplications", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Queryfunnel records** — Run a unique-visitor funnel and return conversion and timing metrics for an ordered sequence of 2-3 steps * **Objecteventbreakdown records** — Rank or trend the events/actions on one kind of business OBJECT (e.g * **Objectanalyticstimeseries records** — Track how engagement with a business OBJECT (e.g * **Objectanalyticsbreakdown records** — Analyze the individual business OBJECTS (e.g * **Objectanalyticsactivecount records** — Count how many unique business OBJECTS (e.g * **Listvisitors records** — List the visitors that match a segment and get a summary of the cohort ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # PhantomBuster connector > Connect to PhantomBuster to automate web scraping and data extraction workflows. Launch, monitor, and manage automation agents that extract data from... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your PhantomBuster credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'phantombuster' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'phantombuster_companies_search', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "phantombuster" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="phantombuster_companies_search", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update user** — Update profile information for the current PhantomBuster user * **Fetch user, script code, org** — Get information about the current PhantomBuster user, including profile details, plan, and organization membership * **Save script, companies, leads** — Create a new custom PhantomBuster script or update an existing one * **Delete script, leads, branch** — Permanently delete a custom PhantomBuster script by its ID * **List save, fetch, delete** — Create or update a lead list in PhantomBuster organization storage, defined by a name and a filter over stored leads * **Search leads objects, identities, companies** — Search structured lead objects stored in PhantomBuster organization storage, optionally filtered by field criteria ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # PhantomBuster MCP connector > Connect to PhantomBuster MCP server to launch and manage web automation agents, retrieve scraping outputs, manage leads, and explore workspace resources... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'phantombustermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize PhantomBuster MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'phantombustermcp_identities_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "phantombustermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize PhantomBuster MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="phantombustermcp_identities_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update users** — Updates the current authenticated user’s profile information * **Fetch users, scripts** — Retrieves the current authenticated user’s profile information including account details and session data * **Visibility scripts** — Updates the visibility of a script branch on PhantomBuster * **Save scripts, orgs, org storage lists** — Creates a new script or updates an existing one on PhantomBuster * **Delete scripts, org storage lists, org storage leads objects** — Deletes a PhantomBuster script by its ID * **Code scripts** — Gets the source code of a PhantomBuster script by name ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pipedrive connector > Connect to Pipedrive CRM. Manage deals, contacts, organizations, activities, leads, and notes to streamline your sales pipeline. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Pipedrive credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pipedrive' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Pipedrive:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pipedrive_activities_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pipedrive" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Pipedrive:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pipedrive_activities_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update user, filter, deal product** — Update a Pipedrive user’s activation status * **Create user, filter, person** — Invite a new user to the Pipedrive account by email, optionally setting their app access level and active status * **List stage deals, product followers, product fields** — List the deals currently sitting in a specific pipeline stage, optionally filtered by owner or a saved filter * **Delete product follower, person follower, organization follower** — Remove a follower from a product in Pipedrive * **Add product follower, person follower, organization follower** — Add a user as a follower of a product so they receive updates about it in Pipedrive * **Statistics pipeline movement, pipeline conversion** — Get counts of how deals moved into and out of each stage of a pipeline over a given date range ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pipedrive MCP connector > Connect to Pipedrive CRM via MCP to manage deals, contacts, organizations, leads, activities, and notes directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pipedrivemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Pipedrive MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pipedrivemcp_addactivity', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pipedrivemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Pipedrive MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pipedrivemcp_addactivity", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Updatelead records** — Updates one or more properties of a lead * **Getleads records** — Returns a paginated list of non-archived leads sorted by creation time * **Getlead records** — Returns full details of a specific lead by ID, including title, value, expected close date, and linked person/organization * **Addlead records** — Creates a new lead and links it to a person, organization, or both (at least one required) * **Updateperson records** — Modifies an existing contact person’s properties such as name, email, phone, organization, or custom fields * **Updateorganization records** — Modifies an existing organization’s properties such as name, address, owner, or custom fields ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pixelbin MCP connector > Image and video transformation, optimization, and management platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pixelbinmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Pixelbin MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pixelbinmcp_list_predictions', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pixelbinmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Pixelbin MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pixelbinmcp_list_predictions", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Url upload asset from, request upload** — Ingest a publicly-reachable URL into the user’s PixelBin storage * **Storage save prediction to** — Persist a completed prediction’s output to the user’s PixelBin storage as a permanent asset * **List predictions** — List available PixelBin prediction plugins and operations * **Get prediction** — Poll a PixelBin prediction by id * **Cost estimate prediction** — Estimate the credits a PixelBin prediction will consume before running it * **Create prediction** — Start a PixelBin prediction (e.g ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Plain MCP connector > Connect to Plain MCP. Manage customer support threads, labels, tenants, Help Center articles, and thread field schemas directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'plainmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Plain MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'plainmcp_getcustomers', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "plainmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Plain MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="plainmcp_getcustomers", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Startsidekicksession records** — Start a new Sidekick (Plain’s AI agent) session and return the handle used by every other Sidekick tool * **Sendsidekickmessage records** — Send a follow-up message into an existing Sidekick session * **Searchthreadlinkcandidates records** — Search a connected issue tracker for external entities that can be linked to a thread via createThreadLink * **Resolvesidekickapproval records** — Approve or deny a Sidekick tool-call approval request * **Mergethread records** — Merge one Plain thread into another (a MERGED\_INTO native thread link) * **Listsidekicksessions records** — List Sidekick sessions in the workspace, most recent activity first ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Plane MCP connector > Connect to Plane MCP. Manage projects, work items, cycles, modules, epics, and initiatives in your Plane workspace from AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'planemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Plane MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'planemcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "planemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Plane MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="planemcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update workspace features, work log, work item type** — Enable or disable feature flags for the workspace * **Module unarchive, retrieve, remove work item from** — Restore an archived module to active status * **Cycle unarchive, retrieve, remove work item from** — Restore an archived cycle to active status * **Items transfer cycle work** — Move all incomplete work items from one cycle to another * **Search work items** — Search for work items by name or description across the workspace * **Page retrieve workspace, retrieve project** — Retrieve the content and metadata of a workspace-level page ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Planet Scale MCP connector > Connect to PlanetScale MCP. Run SQL queries, inspect database branches and schemas, get query performance insights, and manage organizations and invoices... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'planetscalemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Planet Scale MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'planetscalemcp_planetscale_execute_read_query', 25 toolInput: { organization: 'YOUR_ORGANIZATION', database: 'YOUR_DATABASE', branch: 'YOUR_BRANCH', query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "planetscalemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Planet Scale MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"organization":"YOUR_ORGANIZATION","database":"YOUR_DATABASE","branch":"YOUR_BRANCH","query":"YOUR_QUERY"}, 27 tool_name="planetscalemcp_planetscale_execute_read_query", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search planetscale** — Search the PlanetScale knowledge base for documentation, API references, code examples, and guides * **List planetscale** — List all schema recommendations for a PlanetScale database based on production query patterns * **Get planetscale** — Get details about a specific PlanetScale organization * **Execute planetscale** — Execute a write SQL query (INSERT, UPDATE, DELETE, or DDL) against a PlanetScale database branch ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Planning Center MCP connector > Planning Center is a church management platform with modules for people (contact database), giving, check-ins, services planning, groups, registrations... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'planningcentermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Planning Center MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'planningcentermcp_check_ins_check_ins', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "planningcentermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Planning Center MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="planningcentermcp_check_ins_check_ins", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Speakers publishing** — Search speakers in Planning Center Publishing * **Series publishing** — Search sermon series in Planning Center Publishing * **Episodes publishing** — Search episodes in Planning Center Publishing * **Statistics publishing episode** — Church Center viewership statistics for the episodes in a single Publishing channel * **Channels publishing** — Search sermon channels in Planning Center Publishing * **Refunds giving** — Get the refund on a single donation in Planning Center Giving - the amount refunded, the payment processing fee returned, and when the refund was processed ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Plaud MCP connector > Connect to Plaud MCP. Browse your Plaud recordings, read AI-generated notes, and pull timestamped transcripts with speaker labels into your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'plaudmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Plaud MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'plaudmcp_get_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "plaudmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Plaud MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="plaudmcp_get_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List recordings** — browse Plaud recordings, narrowed by a name substring and an inclusive `date_from`/`date_to` range * **Get recording details** — read a recording’s name, timestamps, duration, transcript segments, AI notes, and temporary audio download URL * **Read timestamped transcripts** — fetch raw or AI-cleaned transcripts with speaker attribution, one cursor-paginated page of utterances at a time * **Read AI-generated notes** — retrieve the summary, action items, and key topics for a recording as Markdown blocks * **Identify the connected account** — confirm which Plaud account the current tool calls run against ## Common workflows [Section titled “Common workflows”](#common-workflows) `plaudmcp_get_file`, `plaudmcp_get_note`, and `plaudmcp_get_transcript` require a **file ID** — the identifier of a single recording. Start with `plaudmcp_list_files` to discover recordings, then pass a `file_id` to the details, notes, or transcript tools. ### Find a recording, then read its notes Filter the recording list by name substring or date range, take the `file_id` of a match, and fetch the AI-generated summary and action items. * Node.js ```typescript 1 // Step 1 — find the recording. `query` matches the name, case-insensitively. 2 const listResult = await scalekit.actions.executeTool({ 3 toolName: 'plaudmcp_list_files', 4 identifier: 'user_123', 5 connector: 'plaudmcp', 6 toolInput: { 7 query: 'weekly sync', 8 date_from: '2026-01-01', 9 date_to: '2026-01-31', 10 }, 11 }); 12 13 // Inspect the payload once to learn how Plaud names the recording list and 14 // its file IDs, then read those fields directly in your own code. 15 // Security: Log only in development; recording names may expose user data. 16 console.log(listResult.data); 17 18 // Step 2 — read the AI notes for a recording you picked from that payload. 19 const noteResult = await scalekit.actions.executeTool({ 20 toolName: 'plaudmcp_get_note', 21 identifier: 'user_123', 22 connector: 'plaudmcp', 23 toolInput: { file_id: '66f2b1c8e4b0a1d2c3e4f5a6' }, 24 }); 25 26 // Security: AI notes summarize the recording. Log only in development, and 27 // pass the notes to your agent rather than persisting them. 28 console.log(noteResult.data); ``` * Python ```python 1 # Step 1 — find the recording. `query` matches the name, case-insensitively. 2 list_response = actions.execute_tool( 3 tool_name="plaudmcp_list_files", 4 identifier="user_123", 5 connection_name="plaudmcp", 6 tool_input={ 7 "query": "weekly sync", 8 "date_from": "2026-01-01", 9 "date_to": "2026-01-31", 10 }, 11 ) 12 13 # Inspect the payload once to learn how Plaud names the recording list and 14 # its file IDs, then read those fields directly in your own code. 15 # Security: Log only in development; recording names may expose user data. 16 print(list_response.data) 17 18 # Step 2 — read the AI notes for a recording you picked from that payload. 19 note_response = actions.execute_tool( 20 tool_name="plaudmcp_get_note", 21 identifier="user_123", 22 connection_name="plaudmcp", 23 tool_input={"file_id": "66f2b1c8e4b0a1d2c3e4f5a6"}, 24 ) 25 26 # Security: AI notes summarize the recording. Log only in development, and 27 # pass the notes to your agent rather than persisting them. 28 print(note_response.data) ``` ### Page through a long transcript `plaudmcp_get_transcript` returns one page of utterances at a time and includes a `next_cursor` when more remain. Pass that cursor back on the next call, and stop when the response returns no cursor. * Node.js ```typescript 1 const pages = []; 2 let cursor: string | undefined = undefined; 3 4 do { 5 const result = await scalekit.actions.executeTool({ 6 toolName: 'plaudmcp_get_transcript', 7 identifier: 'user_123', 8 connector: 'plaudmcp', 9 toolInput: { 10 file_id: '66f2b1c8e4b0a1d2c3e4f5a6', 11 block: 'transaction', // raw transcript with speaker names and timestamps 12 limit: 200, 13 ...(cursor ? { cursor } : {}), 14 }, 15 }); 16 17 pages.push(result.data); 18 cursor = (result.data as { next_cursor?: string }).next_cursor; 19 } while (cursor); 20 21 console.log(`Fetched ${pages.length} transcript page(s)`); ``` * Python ```python 1 pages = [] 2 cursor = None 3 4 while True: 5 tool_input = { 6 "file_id": "66f2b1c8e4b0a1d2c3e4f5a6", 7 "block": "transaction", # raw transcript with speaker names and timestamps 8 "limit": 200, 9 } 10 if cursor: 11 tool_input["cursor"] = cursor 12 13 response = actions.execute_tool( 14 tool_name="plaudmcp_get_transcript", 15 identifier="user_123", 16 connection_name="plaudmcp", 17 tool_input=tool_input, 18 ) 19 20 pages.append(response.data) 21 cursor = response.data.get("next_cursor") 22 if not cursor: 23 break 24 25 print(f"Fetched {len(pages)} transcript page(s)") ``` ### Choose the right transcript block `plaudmcp_get_transcript` reads one of three blocks. Pick the block that matches what the agent needs: | Block | Returns | Use it when | | -------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | `transaction` | Raw utterances with speaker labels and timestamps. This is the default. | Exact wording matters — quoting, compliance review, or speaker attribution | | `transaction_polish` | The same per-utterance shape, cleaned up by AI. Keeps speaker and timestamps. | You want readable prose without filler words, but still need timestamps | | `outline` | A structured outline of the recording. | You need the shape of the conversation rather than its full text | ### Get one recording’s metadata and audio `plaudmcp_get_file` returns everything about a single recording in one call: name, timestamps, duration, transcript segments, AI notes, and a temporary audio download URL. * Node.js ```typescript 1 const result = await scalekit.actions.executeTool({ 2 toolName: 'plaudmcp_get_file', 3 identifier: 'user_123', 4 connector: 'plaudmcp', 5 toolInput: { file_id: '66f2b1c8e4b0a1d2c3e4f5a6' }, 6 }); 7 8 // Security: Log only in development; recordings may contain sensitive content. 9 console.log(result.data); ``` * Python ```python 1 response = actions.execute_tool( 2 tool_name="plaudmcp_get_file", 3 identifier="user_123", 4 connection_name="plaudmcp", 5 tool_input={"file_id": "66f2b1c8e4b0a1d2c3e4f5a6"}, 6 ) 7 8 # Security: Log only in development; recordings may contain sensitive content. 9 print(response.data) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Posthog MCP connector > Connect to Posthog MCP to enable your AI agents and tools to directly interact with PostHog's products. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'posthogmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Posthog MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'posthogmcp_activity_log_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "posthogmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Posthog MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="posthogmcp_activity_log_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Exec records** — ### Using the `posthog` tool PostHog makes your product self-driving: it reads your data and ships changes with you, never without you * **List workflows, view, subscriptions** — List all workflows in the project * **Get workflows, view, surveys** — Get a specific workflow by ID * **Update view, feature flag, survey** — Update an existing data warehouse saved query (view) * **Unmaterialize view** — Undo materialization for a saved query * **Run view, evaluation** — Get the 5 most recent materialization run statuses for a saved query ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Postman MCP connector > Connect to the Postman MCP server to manage collections, workspaces, environments, and APIs directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'postmanmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Postman MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'postmanmcp_createworkspace', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "postmanmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Postman MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="postmanmcp_createworkspace", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Updateworkspace records** — Updates a workspace’s property, such as its name or visibility * **Updatespecproperties records** — Updates an API specification’s properties, such as its name * **Updatespecfile records** — Updates a file for an OpenAPI or protobuf 2 or 3 specification * **Updatemock records** — Updates a mock server * **Updatecollectionrequest records** — Updates a request in a collection * **Syncspecwithcollection records** — Syncs an API specification linked to a collection ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Postmark connector > Send and track transactional and broadcast email with Postmark. Manage templates, message streams, bounces, suppressions, webhooks, and delivery... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Postmark credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'postmark' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'postmark_get_bounce_counts', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "postmark" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="postmark_get_bounce_counts", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Send bulk email, email with template, email** — Send one message (subject and body defined once) to a large list of recipients via Postmark’s Bulk Email API — distinct from the Batch API (Send Batch Emails), which sends a different message per recipient in one call * **Get bulk email status, webhook, tracked email counts** — Check the processing status of a previously submitted Bulk Email send: overall status (Accepted, Processing, or Completed), percent complete, and total message count * **Template validate** — Validate template content without saving it, rendering subject, html\_body, and/or text\_body against test\_render\_model to surface syntax errors and preview the rendered output * **Update webhook, template, server info** — Update an existing webhook on the current Postmark server by its numeric ID * **Stream unarchive message, archive message** — Unarchive a previously archived message stream on the current Postmark server, restoring it to active use before its 30-day deletion window elapses * **Message retry inbound, bypass inbound** — Retry processing of an inbound message that previously failed, causing Postmark to attempt delivery to your configured inbound webhook again ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Prisma MCP connector > Connect to Prisma MCP. Manage Prisma Postgres databases, run SQL queries, handle backups, and manage connection strings from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'prismamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Prisma MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'prismamcp_fetch_workspace_details', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "prismamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Prisma MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="prismamcp_fetch_workspace_details", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search prisma documentation** — Search Prisma’s official documentation and knowledge sources to answer questions about Prisma Postgres, Prisma ORM, Accelerate, Optimize, schema design, and migrations * **List object store buckets, prisma postgres databases, prisma postgres connection strings** — List object-store buckets in the workspace, 100 per page, optionally filtered by project ID * **Delete object store bucket key, object store bucket, prisma postgres database** — Delete an object-store bucket access key * **Create object store bucket key, object store bucket, prisma postgres recovery** — Create an S3-compatible access key for an object-store bucket * **Schema introspect database** — Introspect and return the schema of a Prisma Postgres database as JSON * **Fetch workspace details** — Retrieve details of the current Prisma Postgres workspace, including plan limits and usage ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Privacy MCP connector > Connect to Privacy MCP. Create and manage virtual cards, set spend limits, pause or close cards, and review transactions from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'privacymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Privacy MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'privacymcp_list_cards', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "privacymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Privacy MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="privacymcp_list_cards", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update card spend limit, card memo** — Update the spend limit and optional reset duration for a virtual card * **Card unpause, pause, close** — Re-enable transactions on a previously paused virtual card * **List transactions, cards** — List transactions on your Privacy.com account, with optional filters for card, date range, and result * **Get pan, card** — Retrieve the full card number (PAN), CVV2, and expiration date for a virtual card * **Create card** — Create a new virtual card on your Privacy.com account with optional spend limits and memo ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Profound MCP connector > Profound is an AI search visibility and marketing analytics platform that helps brands understand and optimize their presence across AI-powered answer... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'profoundmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Profound MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'profoundmcp_list_models', 25 toolInput: { rationale: 'YOUR_RATIONALE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "profoundmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Profound MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"rationale":"YOUR_RATIONALE"}, 27 tool_name="profoundmcp_list_models", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Whoami records** — Confirm the authenticated user, organizations, regions, and entitlements available to this MCP session * **List topics, tags, regions** — List topics available within a category for filtering prompts and reports * **Get visibility report, sentiment report, referrals report** — Measure how often and how prominently a brand appears in AI answers for a category over a date range ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ProhostAI MCP connector > ProhostAI is an AI-powered property management platform for Airbnb hosts and property managers, offering AI guest messaging, task/cleaning automation... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'prohostaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ProhostAI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'prohostaimcp_drive_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "prohostaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ProhostAI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="prohostaimcp_drive_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Photo upload place, upload contact** — Return a presigned PUT URL for uploading a place photo to S3 * **Image upload guidebook** — Return a presigned PUT URL for uploading a guidebook image to S3 * **Attachment upload cleaning** — Register one or more attachment URLs on a cleaning * **Update workflow, upgrade option, task checklist** — Update an existing automation workflow in place * **Dates unblock, block** — Unblock (mark available) a list of dates on a listing’s calendar * **Checklist translate task** — Translate a task checklist to a target language ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ProShort AI connector > Connect to ProShort AI to search and retrieve AI-analyzed sales call recordings, transcripts, and summaries. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'proshortai' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'proshortai_recordings_search', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "proshortai" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="proshortai_recordings_search", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search recordings** — Search and filter ProShort meeting recordings by title text, date range, attendee email, and conferencing platform * **Get recordings** — Retrieve a ProShort recording via the v2 endpoint ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pylon connector > Connect to Pylon, the modern customer support platform, to manage tickets, contacts, accounts, tasks, projects, and knowledge base content. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pylon' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'pylon_accounts_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pylon" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="pylon_accounts_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search users, tasks, surveys** — Search for Pylon users using a filter * **List users, user roles, training data** — Returns all users (agents/teammates) for the organization, including their name, email, and role * **Update user, team, task** — Update an existing Pylon user * **Get user, training data, ticket form** — Retrieve a single Pylon user by their ID * **Files training data upload** — Upload a single file as training data, either into a new training data container or an existing one * **Content training data upload** — Upload plain text content as a training data document, either into a new training data container or an existing one ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Pylon MCP connector > Connect to Pylon MCP. Manage customer issues, accounts, projects, milestones, and tasks from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'pylonmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Pylon MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'pylonmcp_get_me', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "pylonmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Pylon MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="pylonmcp_get_me", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get agent issue, user, tasks** — Retrieve an AI agent’s full event and action timeline on a specific issue, including tool calls, runbook steps, reassignments/escalations, messages, and outcomes * **Create attachment, task, project from template** — Upload a base64-encoded file to Pylon and return its attachment ID and URL * **Files upload account** — Upload one or more files to an account * **Update task, project, milestone** — Update a task title, status, assignee, due date, or other fields by its ID * **Search tasks, projects, issues** — Search tasks by text, project, account, assignee, and status * **Delete task** — Permanently delete a task by its ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # QuickBooks connector > Connect to QuickBooks Online. Manage customers, vendors, invoices, bills, payments, and financial reports. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your QuickBooks credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'quickbooks' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize QuickBooks:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'quickbooks_company_info_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "quickbooks" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize QuickBooks:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="quickbooks_company_info_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get time activity, tax rate, purchase** — Retrieve a single QuickBooks Online time activity by ID * **Create time activity, purchase, vendor credit** — Create a new time activity (billable or non-billable time entry) for an employee or vendor in QuickBooks Online * **List time activities, tax rates, report transaction** — List time activities from QuickBooks Online via the SQL-like query endpoint (entity=TimeActivity), matching the existing list-tool pattern used for other entities * **Update sales receipt, refund receipt, purchase** — Update an existing sales receipt in QuickBooks Online * **Balance report vendor, report customer, report trial** — Retrieve a Vendor Balance report from QuickBooks Online * **Delete refund receipt, purchase, sales receipt** — Delete a refund receipt in QuickBooks Online ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Quicknode MCP connector > Connect to QuickNode MCP. Create and manage blockchain RPC endpoints, configure security rules, set rate limits, and monitor usage and logs from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'quicknodemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Quicknode MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'quicknodemcp_list-chains', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "quicknodemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Quicknode MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="quicknodemcp_list-chains", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update-endpoint-security-options records** — Update security settings (CORS, HSTS, IP allowlists, JWT, tokens, referrers, domain masks) for a QuickNode endpoint * **Update-endpoint-rate-limits records** — Update the general rate limits (requests per second, minute, or day) for a QuickNode endpoint * **Update-endpoint-method-rate-limit records** — Update the rate, interval, or status of an existing method-specific rate limit on a QuickNode endpoint * **List-endpoints records** — List all web3 RPC endpoints in the user’s QuickNode account with optional pagination * **List-endpoint-security records** — List all security options and rules configured for a QuickNode endpoint * **List-endpoint-method-rate-limits records** — List all method-specific rate limits configured for a QuickNode endpoint ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Quiz.Video MCP connector > Quiz.Video is an AI-powered platform for creating short-form quiz and flashcard videos. Transform topics, URLs, or documents into shareable quiz and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'quizvideomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Quiz.Video MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'quizvideomcp_get_api_catalog', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "quizvideomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Quiz.Video MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="quizvideomcp_get_api_catalog", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update quiz video** — Update an existing template * **List quiz video** — List the caller’s saved custom templates (and optionally public ones) * **Get quiz video** — Fetch a single custom template (including the full scenes/layers payload) by id * **Quiz video generate quiz** — AI-generate and save a quiz from a topic * **Render quiz video download** — Request a signed download URL for a completed render * **Delete quiz video** — Permanently delete a custom template you own ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Quo MCP connector > Connect to Quo MCP. Access call details, summaries, transcripts, and voicemails, send text messages, and create or update contacts from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'quomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Quo MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'quomcp_list_contacts', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "quomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Quo MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="quomcp_list_contacts", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update task, contact** — Update a Quo task * **Send message, group message, bulk messages** — Send an SMS text message from a Quo inbox to a single recipient * **List users, tasks, inboxes** — List the users (members) in the Quo workspace * **Get contact** — Fetch a single Quo contact by ID, including its default fields (name, company, role, email, phone) and any custom fields configured on the workspace * **Fetch missed calls, messages, call transcripts** — Fetch missed incoming calls for a Quo inbox, each enriched with the voicemail the caller left (transcript + recording URL) when there is one * **Create task, contact** — Create a task in Quo linked to exactly one inbox, conversation, or conversation activity ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Read AI MCP connector > Connect to Read AI to access your meeting intelligence — transcripts, summaries, action items, and insights from meetings, emails, and chats. Retrieve... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'readaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Read AI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'readaimcp_list_meetings', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "readaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Read AI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="readaimcp_list_meetings", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Report share meeting** — Share a Read AI meeting report with an email address on behalf of the authenticated user * **List meetings** — List Read AI meetings for the authenticated user with optional start-time filters and cursor-based pagination * **Get meeting by id** — Retrieve a single Read AI meeting by its ULID identifier, with optional expansion of rich meeting content such as summary, transcript, action items, topics, metrics, and recording download link * **Create meeting agent** — Send a Read AI meeting agent (bot) to a video conferencing meeting to record and transcribe it ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Recraft AI MCP connector > Connect to Recraft AI MCP. Generate AI-powered images, vectors, icons, and mockups from your AI agents using Recraft's creative design tools. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'recraftmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Recraft AI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'recraftmcp_get_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "recraftmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Recraft AI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="recraftmcp_get_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Edit image** — Edit one or more input images according to a text prompt, producing new image(s) * **Agent call** — Talk to Recraft’s Design Agent in a multi-turn chat to turn a brief for a digital product into a coherent set of design assets (logo, colour palette, typography, app icon, social assets) and optionally save them as a reusable Design Kit * **Image vectorize, variate, inpaint** — Convert a raster image to a vector format * **Model suggest** — Suggest the best Recraft image generation model for a given user request * **Plans subscription** — List available Recraft subscription plans with their credits, refill periods, and pricing * **Url request upload** — Issue an upload URL for a direct image upload ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Reddit connector > Connect to Reddit to access user identity, subreddit data, posts, comments, and mod tools. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Reddit credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'reddit' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Reddit:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'reddit_inbox_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "reddit" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Reddit:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="reddit_inbox_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List wiki pages, subreddits new** — Get the list of wiki pages in a subreddit * **Revisions wiki page** — Get the revision history of a specific wiki page * **Get wiki page, user flair, unread** — Get the content and metadata of a wiki page in a subreddit * **Edit wiki page, content** — Edit or create a wiki page in a subreddit * **Vote records** — Cast an upvote (1), downvote (-1), or remove vote (0) on a post or comment identified by its fullname * **Upvoted user** — Get the posts and comments upvoted by a user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # AWS Redshift connector > Amazon Redshift is a fully managed cloud data warehouse that enables fast, cost-effective analysis of structured and semi-structured data at scale. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List databases, tables, statements** — List the databases available in the connected Amazon Redshift cluster or serverless workgroup, using the Redshift Data API * **Statement describe** — Get the status, duration, and row count of a previously submitted statement without fetching result rows * **Execute batch, sql** — Run multiple SQL statements serially in a single call against Amazon Redshift using the Redshift Data API’s BatchExecuteStatement action, returning one batch statement ID * **Get query result** — Retrieve the results of a previously executed Redshift SQL statement using the statement ID returned by redshift\_execute\_sql * **Table describe** — Describe the schema of a table in Amazon Redshift using the Redshift Data API, including column names, types, and metadata * **Query cancel** — Cancel a running Amazon Redshift SQL statement using its statement ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Replit MCP connector > Connect to Replit MCP. Create, update, and inspect Replit apps from natural-language prompts, list your apps, and resolve apps by name from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'replitmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Replit MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'replitmcp_list_apps', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "replitmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Replit MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="replitmcp_list_apps", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update app using prompt** — Update an existing Replit app using a natural-language description of the desired change * **Name resolve app by** — Look up an existing Replit app by its exact name and return its repl ID and URL for use in other tools * **Preview replit widget start app** — Internal Replit widget tool that starts an app preview session for a given repl * **Get replit widget** — Internal Replit widget tool that retrieves the preview URL for a running repl build * **List apps** — List the authenticated user’s Replit apps, most recently updated first, with optional name filtering * **Create app from prompt** — Create a new Replit app from a natural-language description in the authenticated user’s account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Resend connector > Resend is an email API platform for developers. Send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Resend credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'resend' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'resend_api_key_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "resend" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="resend_api_key_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List webhook events, webhook event attempts, broadcast recipients** — Retrieve the delivery event log for a webhook endpoint — each entry is one event Resend attempted to deliver, with its type and delivery status (success, failed, attempting, or pending) * **Get webhook event, segment metrics, email metrics** — Retrieve a single webhook delivery event by ID, including its type, delivery status, next retry time (if still attempting), and the full event payload that was (or will be) sent to the endpoint * **Cancel broadcast, email** — Cancel a broadcast that is currently queued or scheduled, stopping any further emails from being sent * **Update webhook, topic, template** — Update an existing webhook in the Resend account: its endpoint URL, the array of event types it subscribes to, and/or its status (enabled/disabled) * **Delete webhook, topic, template** — Permanently remove an existing webhook from the Resend account * **Create webhook, topic, template** — Create a new webhook endpoint to receive Resend email, contact, and domain event callbacks ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Resend MCP connector > Connect to Resend's official MCP server to send transactional and marketing emails, manage sending domains, contacts, audiences, broadcasts, and templates... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'resendmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'resendmcp_get_automation', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "resendmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="resendmcp_get_automation", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Claim verify domain** — Trigger asynchronous DNS verification and ownership transfer for a domain claim, using the placeholder Domain ID * **Domain verify, remove** — Trigger domain verification in Resend * **Update webhook, topic, template** — Update an existing webhook in Resend * **Send event, email, broadcast** — **Purpose:** Fire an event to trigger automations for a specific contact * **Grant revoke oauth** — Revoke an OAuth grant by ID * **Webhook remove** — Remove a webhook by ID from Resend ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Revealed AI MCP connector > Connect to Revealed AI. Track account signals, buyer personas, and people changes to surface timely outreach actions and account intelligence for B2B... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'revealedaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Revealed AI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'revealedaimcp_list_accounts', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "revealedaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Revealed AI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="revealedaimcp_list_accounts", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Actions top, recommended** — Retrieve ranked recommended actions across all active accounts in the workspace * **Changes recent** — Retrieve what changed since the last finalized snapshot: change summary, person changes, and signal events * **Usage plan** — Retrieve billing plan limits and current account usage counts for the workspace * **Status mcp** — Check MCP connectivity and return workspace name, OAuth client ID, and granted token scopes * **List tracked signals, personas, people** — List persona slugs, people signal slugs, and company signal slugs configured for this workspace * **Get person, company signal, account brief** — Retrieve the full person record from the latest snapshot ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Rize MCP connector > Connect to Rize MCP using OAuth 2.1 with MCP discovery and dynamic client registration. Access and analyze your time tracking data, projects, clients... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'rizemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Rize MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'rizemcp_get_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "rizemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Rize MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="rizemcp_get_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update workspace agent context, team agent context, tagging settings** — Set the workspace’s standing agent guidance — injected into every member’s agent runs (chat, reports, routines, tagging) * **Search my meetings** — Search the current user’s calendar events and meeting transcripts over a date range * **Member remove team, invite team** — Remove a member from a team * **Query org context** — Search an organization’s uploaded context documents (contracts, invoices, PDFs, etc.) using semantic retrieval * **List workspace members, teams, skills** — List the workspace (organization) roster with per-team assignments * **Get tagging settings, skill, routine run** — Get the current user’s auto-tagging settings: generation mode, entry duration preferences, auto-approve threshold, which tag dimensions are automated, the custom instructions for tagging and activity summaries, and the agent guidance layered onto their runs (personal, plus their default team/workspace guidance) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Roam MCP connector > Connect to Roam MCP. Access and manage meetings, transcripts, chat messages, calendar events, and people data across your Roam virtual office workspace. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'roammcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Roam MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'roammcp_calendar_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "roammcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Roam MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="roammcp_calendar_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Unsubscribe webhook** — Unsubscribe from a webhook by ID * **Subscribe webhook** — Subscribe to receive webhook events at a URL * **Deliveries webhook** — List recent FAILED webhook delivery attempts for the authenticated client — timeouts (statusCode 0, error “timeout”), connection errors, and non-2xx responses * **List user, reaction, onair guest** — List users (people) in your workspace * **Info user, token, onair guest** — Resolve a member, guest, or automated actor by user ID * **Post story, chat** — Post a photo or video story to the caller’s Roam ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Runware MCP connector > Connect to Runware's MCP server to generate and edit images, video, audio, and 3D assets using thousands of AI models through a single API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'runwaremcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Runware MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'runwaremcp_list_capabilities', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "runwaremcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Runware MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="runwaremcp_list_capabilities", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Storage media** — Store or delete media (images, video, audio, 3D models) in your Runware account * **Run records** — Run an AI inference task on Runware * **Upload model** — Upload a custom AI model to Runware (checkpoint, LoRA, VAE, embeddings, etc.) * **Search model** — Search Runware’s Civitai mirror and community-uploaded models — third-party fine-tunes, user uploads, style LoRAs, custom checkpoints * **Schema model** — Get the parameter schema for a specific model * **Pricing model** — Get pricing details for a curated Runware model — overview text plus example configurations with prices (e.g ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Salesforce connector > Connect to Salesforce CRM. Manage leads, opportunities, accounts, and customer relationships 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Salesforce credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'salesforce' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Salesforce:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'salesforce_limits_get', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "salesforce" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Salesforce:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="salesforce_limits_get", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Read CRM records** — retrieve accounts, contacts, leads, opportunities, and cases by ID or search query * **Create and update records** — open leads, close opportunities, update deal stages, and edit contacts * **Log activities** — create tasks and events linked to any CRM record * **Run SOQL queries** — execute arbitrary Salesforce Object Query Language queries for custom data retrieval * **Search across objects** — find records by name, email, phone, or any field value * **Call the Metadata API** — use [SOAP proxy calls](#call-the-metadata-api-through-soap-proxy) to inspect and modify Salesforce org metadata ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… ## Clone dashboards [Section titled “Clone dashboards”](#clone-dashboards) To rename a cloned dashboard, use a two-step pattern: 1. Call `salesforce_dashboard_clone` with the source dashboard ID. 2. Call `salesforce_dashboard_update` with the cloned dashboard ID and the new name. ```json 1 { 2 "dashboard_id": "", 3 "name": "New dashboard name" 4 } ``` See the [Salesforce Dashboard clone API](https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_clone_dashboard.htm) for clone payload fields. ## Call the Metadata API through SOAP proxy [Section titled “Call the Metadata API through SOAP proxy”](#call-the-metadata-api-through-soap-proxy) The [Salesforce Metadata API](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_intro.htm) is a SOAP-based API for reading and modifying your Salesforce org’s configuration, not its data. Use it to inspect or deploy custom objects, page layouts, validation rules, Apex classes, permission sets, profiles, and other org metadata. Salesforce SOAP APIs only accept opaque access tokens, not JSON Web Token (JWT) access tokens. In your Salesforce Connected App, make sure **Issue JSON Web Token (JWT)-based access tokens for named users** is unchecked. If you disable this option after users have already authenticated, users must re-authenticate before SOAP proxy calls work. ### Get the API version for the connected account The Metadata API SOAP endpoint URL requires a version number. Retrieve the version from the connected account’s `api_config`. ```python 1 import os 2 3 import scalekit.client 4 from dotenv import load_dotenv 5 6 load_dotenv() 7 8 connection_name = "salesforce" # Connection name from the Scalekit dashboard 9 identifier = "6fe1c057-f684-4303-9555-3dd8807319b4" # Your user's identifier as registered in Scalekit 10 11 scalekit_client = scalekit.client.ScalekitClient( 12 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 13 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 14 env_url=os.getenv("SCALEKIT_ENV_URL"), 15 ) 16 actions = scalekit_client.actions 17 18 result = actions.get_connected_account( 19 connection_name=connection_name, 20 identifier=identifier, 21 ) 22 23 raw_version = result.connected_account.api_config.get("version") 24 if not raw_version: 25 raise ValueError("Salesforce connected account is missing api_config.version") 26 27 api_version = raw_version.lstrip("v") # e.g. "66.0" ``` 1. ## Build the SOAP body Construct the SOAP envelope for the operation you want to call. Do not include a `` element. Scalekit injects the session header with the connected account’s access token. The `soap_body` string uses the `api_version` value from the previous section. ```python 1 soap_body = f""" 2 5 6 7 {api_version} 8 9 10 """ ``` 2. ## Send the SOAP request through Scalekit Pass the SOAP body as `raw_body`. Set `Content-Type` to `text/xml; charset=UTF-8` and `SOAPAction` to the operation name. Scalekit resolves the user’s Salesforce instance URL, so the request only needs the Metadata API path. ```python 1 try: 2 response = actions.request( 3 connection_name=connection_name, 4 identifier=identifier, 5 path=f"/services/Soap/m/{api_version}", 6 method="POST", 7 raw_body=soap_body, 8 headers={ 9 "Content-Type": "text/xml; charset=UTF-8", 10 "SOAPAction": "describeMetadata", 11 }, 12 ) 13 except Exception as exc: 14 raise RuntimeError("Salesforce Metadata API SOAP proxy request failed") from exc 15 16 print(response.content) ``` --- # DOCUMENT BOUNDARY --- # Salesforce Marketing Cloud connector > Connect to Salesforce Marketing Cloud to manage contacts, data extensions, automations, journeys, and email/SMS/push sends across your marketing programs. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Salesforce Marketing Cloud credentials with Scalekit so it handles the token lifecycle. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List workflow teams, tags, sms message** — Retrieve active workflow teams from Salesforce Marketing Cloud’s Approvals Hub REST API (GET /hub/v1/workflowteams/{objecttype}) * **Delete workflow team user, tag, sms keyword** — Permanently remove a user’s assignment from a specific role instance on a workflow item in Salesforce Marketing Cloud, using the Approvals Hub REST API (DELETE /hub/v1/workflowitems/{workflowItemId}/roles/{workflowRoleInstanceId}/Users/{userId}) * **Create workflow team user, tag, sms keyword** — Assign a user to a specific role instance on a workflow item in Salesforce Marketing Cloud, using the Approvals Hub REST API (POST /hub/v1/workflowitems/{workflowItemId}/roles/{workflowRoleInstanceId}) * **Transition workflow item** — Transition a workflow item’s state in Salesforce Marketing Cloud, using the Approvals Hub REST API (POST /hub/v1/workflowitems/{workflowItemId}/transitions) * **Queue sms mo message, sms contact import** — Queue a simulated mobile-originated (MO) message on your MobileConnect short code, primarily used to test keyword flows and double opt-in journeys without needing an actual mobile device to text in * **Get sms mo message history, sms mo message delivery, sms message history** — Retrieve the full interaction history of a queued mobile-originated (MO) message, via GET /sms/v1/queueMO/history/{tokenId} ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Salesloft connector > Connect with Salesloft to manage people, cadences, accounts, activities, emails, calls, and notes 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Salesloft credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'salesloft' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Salesloft:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'salesloft_account_stages_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "salesloft" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Salesloft:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="salesloft_account_stages_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List webhook subscriptions, successes, steps** — Fetch the webhook subscriptions configured for the connected Salesloft application, including each subscription’s callback URL and subscribed event type * **Create webhook subscriptions, person upserts, account upserts** — Create a webhook subscription so Salesloft pushes events (e.g * **Get users, team, opportunities** — Fetch a single Salesloft user by their User ID or User GUID * **Update meetings, tasks, people** — Update a Salesloft meeting by ID * **Delete tasks, people, notes** — Delete a task from Salesloft by its ID ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Sanity MCP connector > Connect to Sanity. Manage structured content, documents, datasets, schemas, releases, and media assets for headless CMS workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sanitymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Sanity MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sanitymcp_list_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sanitymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Sanity MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="sanitymcp_list_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Run sanity cli** — Run a limited subset of Sanity CLI commands and return their output * **Documents patch, unpublish, publish** — Update or edit one or more existing documents by applying precise modifications using @sanity/client patch() operations * **Feedback give sanity** — Submit feedback about Sanity when you encounter issues while working with a Sanity codebase or project * **Upload dataset assets** — Provide local Sanity CLI guidance for uploading an image or file asset to a Content Lake dataset * **Create documents, version, release** — Create one or more draft documents by directly providing structured content * **List cors origins, workspace schemas, sanity rules** — Lists all CORS origins configured for a Sanity project ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Scarpfly MCP connector > Connect to Scrapfly MCP. Scrape web pages, take screenshots, and control a cloud browser with anti-bot bypass, JS rendering, and proxy support. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'scarpflymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Scarpfly MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'scarpflymcp_get_page_url', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "scarpflymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Scarpfly MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="scarpflymcp_get_page_url", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Scrape web** — Fetch a URL with full control over headers, JS rendering, proxy country, anti-scraping protection, and output format * **Get web, page url** — Quickly fetch a URL with sensible defaults and return the page content * **Text type** — Type text at the current cursor position in the active cloud browser session * **Snapshot take** — Take a DOM snapshot of the current page in the cloud browser session * **Screenshot take, cloud browser** — Take a screenshot of the current page in the active cloud browser session * **Option select** — Select an option in a dropdown element in the active cloud browser session ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Scholar Gateway MCP connector > Connect to Scholar Gateway to search Wiley's peer-reviewed academic literature — 8M+ articles from 2,000+ journals spanning sciences, healthcare... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'scholargateway' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Scholar Gateway MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'scholargateway_semanticSearch', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "scholargateway" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Scholar Gateway MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="scholargateway_semanticSearch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **SemanticSearch records** — Searches a full-text academic corpus and returns relevant passages with citation metadata ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Scite MCP connector > Connect to Scite's MCP server to search scientific literature, patents, clinical trials, grants, and FDA drug/device safety data, and manage citation... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'scitemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Scite MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'scitemcp_search_510k_summaries', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "scitemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Scite MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="scitemcp_search_510k_summaries", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update collection** — Update a DOI-list Collection the signed-in user can edit * **Search patents, mhra, maude** — Search patent families from the scite patents database * **Collection remove dois from, add dois to** — Remove DOIs from a Collection * **Get mhra alert, maude report, grant** — Fetch the full text of a single MHRA alert or publication by document ID * **Delete collection** — Permanently delete a Collection * **Create collection** — Create a new Collection owned by the signed-in user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Seismic connector > Connect to Seismic to manage sales enablement content — browse and manage teamsites and library content, work with personal workspace files, search... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'seismic' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Seismic:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'seismic_generative_search', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "seismic" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Seismic:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="seismic_generative_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Version upload workspace file, upload library file** — Upload new content for an existing workspace file, creating a new version while preserving version history * **Update workspace file, library folder, library file** — Update a workspace file’s metadata: rename it and/or move it to a different folder by changing its parentFolderId * **Document unpublish, submit, recall** — Unpublish a previously published library content item, reverting it to draft state so it is no longer visible to end-users on the published channel * **Search content, generative** — Search Seismic content (library and workspace) that the authenticated user has access to, using a full-text search term, optional field-level search/return field selection, filter expressions (by repository, format, dates, custom properties, etc.), and sort order * **Documents publish teamsite** — Immediately publish or schedule publication of up to 10 unpublished Library documents within a teamsite * **List users, user teamsites, user recents** — Get a list of users in the Seismic tenant (legacy endpoint) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Semaphore CI MCP connector > Semaphore CI is a fast, cloud-native continuous integration and delivery platform that automates building, testing, and deploying software with flexible... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'semaphorecimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Semaphore CI MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'semaphorecimcp_organizations_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "semaphorecimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Semaphore CI MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="semaphorecimcp_organizations_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search workflows, projects, docs** — Search recent Semaphore CI workflows for a project, most recent first * **Run workflows, tasks** — Schedule a new Semaphore CI workflow run for a project * **Rerun workflows** — Rerun an existing Semaphore CI workflow * **List tasks, projects, pipelines** — List scheduled tasks (periodics) for a Semaphore CI project * **Describe tasks, jobs** — Get detailed information about a Semaphore CI scheduled task (periodic) * **Jobs pipeline** — List all jobs in a Semaphore CI pipeline ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SendGrid connector > Connect to Twilio SendGrid to send transactional and marketing email at scale, manage templates, contacts, lists, segments, and single sends, verify... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your SendGrid credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sendgrid' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'sendgrid_get_contactdb_upload_status', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sendgrid" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="sendgrid_get_contactdb_upload_status", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update sender identity, contactdb segment, contactdb recipient** — Update an existing Sender Identity used by SendGrid’s legacy Marketing Campaigns ‘Campaigns’ feature, by its numeric sender\_id * **Campaign unschedule, schedule** — Unschedule a Campaign in SendGrid’s legacy Marketing Campaigns feature that has already been scheduled to be sent, returning it to Draft status * **Send test campaign, campaign, test marketing email** — Send a test copy of a Campaign from SendGrid’s legacy Marketing Campaigns feature to a single email address, without affecting the campaign’s Draft/Scheduled status or your real recipients * **Search contactdb recipients by field, contactdb recipient, suppression from asm group** — Search SendGrid’s legacy Marketing Campaigns contact database (contactdb) for recipients matching one or more exact field=value pairs passed directly as the request’s query string, e.g * **Verification reset sender identity, reset sender** — Resend the verification email for a specific unverified Sender Identity used by SendGrid’s legacy Marketing Campaigns ‘Campaigns’ feature, by its numeric sender\_id * **List sender identity, contactdb segment recipients, contactdb segment** — Retrieve a list of all Sender Identities configured for SendGrid’s legacy Marketing Campaigns ‘Campaigns’ feature on this account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Send MCP connector > Connect to Send to create, edit, and share Claude-generated documents as polished web pages with engagement tracking, custom domains, and team asset... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sendmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Send MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sendmcp_get_image_gallery', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sendmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Send MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="sendmcp_get_image_gallery", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Feedback submit** — Sends feedback about Send itself to the team that builds it * **Skill manage** — Create, update, delete, or pin a user-defined skill for this workspace * **Sites manage** — Read or change the settings of an existing site or document made with Send that the user owns, given its share id or URL * **Getsite records** — Fetch an existing Send site or document by share URL or share ID * **Get skills, image gallery** — Fetches skills by ID, lists available skills, or semantically searches them * **Editsite records** — Modifies a Send site or document the user previously created or shared with Send ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Sentry MCP connector > Connect to Sentry MCP server to monitor errors, investigate issues, manage projects, and analyze performance directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sentrymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Sentry MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sentrymcp_find_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sentrymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Sentry MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="sentrymcp_find_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update issue** — Update a Sentry issue’s status or assignment * **Search sentry tools, issues, events** — Search the available Sentry MCP tool catalog by keyword * **Get sentry resource** — Fetch a Sentry resource by URL, or by resourceType plus resourceId * **Projects find** — Find projects within a Sentry organization * **Organizations find** — Find organizations that the user has access to in Sentry * **Execute sentry tool** — Execute any available Sentry MCP tool discovered through the search\_sentry\_tools tool ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ServiceNow connector > Connect to ServiceNow. Manage incidents, service requests, CMDB, and IT service management workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your ServiceNow credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'servicenow' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ServiceNow:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'servicenow_attachment_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "servicenow" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ServiceNow:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="servicenow_attachment_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update user group, sc task, user** — Update fields on an existing user group in ServiceNow, such as its name, description, manager, or active status * **List sc task, user role, user** — Retrieve a list of catalog fulfillment tasks (sc\_task) from ServiceNow, optionally filtered with an encoded query such as `request_item=` to scope to one Requested Item * **Get sc task, sc req item, knowledge base** — Retrieve a specific catalog task (sc\_task) by its sys\_id * **Create sc task, user group, user** — Create a fulfillment task (sc\_task) for a specific Requested Item in ServiceNow Service Catalog * **Resolve problem, incident** — Resolve a problem by setting its state to Closed/Resolved (104) and recording the permanent fix * **Error problem mark known** — Mark a problem as a known error by setting its state to Known Error (102) once the root cause has been identified ## Common workflows [Section titled “Common workflows”](#common-workflows) **Don’t worry about your ServiceNow instance domain in the path.** Scalekit automatically resolves `{{domain}}` from the connected account’s configuration. For example, a request with `path="/api/now/table/sys_user"` will be sent to `https://mycompany.service-now.com/api/now/table/sys_user` automatically. ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SharePoint connector > Connect to SharePoint. Manage sites, documents, lists, and collaborative content 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your SharePoint credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sharepoint' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize SharePoint:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sharepoint_list_followed_sites', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sharepoint" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize SharePoint:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="sharepoint_list_followed_sites", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Page publish site** — Publish a draft or checked-out modern site page in a SharePoint site, making its latest changes visible to other users * **Item move drive, copy drive, restore recycled** — Move a file or folder to a new parent folder in a SharePoint document library, by updating its parentReference * **List site permissions, site pages, drive item children** — List the permission entries (role assignments) granted on a SharePoint site, showing which users, groups, or applications have read, write, or owner access * **Get site permission, site page, drive item** — Retrieve a single permission entry (role assignment) on a SharePoint site by its permission ID, showing the granted roles and the identity they were granted to * **Create site page, folder, subsite** — Create a new modern site page (sitePage) in a SharePoint site’s Site Pages library * **File upload, download, checkout** — Create an upload session for uploading a file to a SharePoint document library ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SignWell connector > SignWell is an e-signature platform for sending, signing, and managing documents. Connect to create and send documents for signature, manage templates... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your SignWell credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'signwell' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'signwell_get_me', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "signwell" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="signwell_get_me", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Send validate bulk, reminder, document** — Validate a bulk send CSV file before creating the bulk send * **Update template, recipients, authentication** — Update an existing document template * **List webhooks, bulk sends** — List all webhook subscriptions configured in the account * **Get template, nom151 certificate, me** — Get a document template and all associated template data including placeholders and fields * **Delete webhook, template, document** — Delete a registered webhook callback URL * **Create webhook, template, document from template** — Register a webhook callback URL to receive document lifecycle events (sent, viewed, signed, completed, declined, etc.) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Slack connector > Connect to Slack workspace. Send Messages as Bots or on behalf of users 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Slack credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'slack' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Slack:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'slack_get_bot_info', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "slack" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Slack:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="slack_get_bot_info", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Send messages** — post to channels, DMs, and threads on behalf of your users * **Read conversations** — retrieve channel history, thread replies, and direct messages * **Manage channels** — create channels, invite members, and update channel settings * **Look up users** — search for team members by name, email, or username * **Upload files** — share files and attachments into any conversation ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Slack MCP connector > Connect to Slack MCP. Send and read messages, search channels and users, manage canvases, and react to messages across your Slack workspace. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Slack MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'slackmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Slack MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'slackmcp_slack_create_conversation', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "slackmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Slack MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="slackmcp_slack_create_conversation", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * Send messages — post to channels, DMs, and threads across your Slack workspace * Read conversations — retrieve channel history, thread replies, and direct messages * Search channels and users — find channels, team members, and public messages by keyword * Manage canvases — create, read, and update Slack Canvas documents * React to messages — add and retrieve emoji reactions on any message * Schedule messages — deliver messages to channels at a specified future time ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Proxy API call * Node.js ```ts 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'slackmcp' 12 const identifier = 'user_123' 13 14 // Read a channel's message history 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'slackmcp_slack_read_channel', 19 toolInput: { channel_id: 'C01234567' }, 20 }) 21 console.log(result) ``` * Python ```python 1 from scalekit import ScalekitClient 2 import os 3 4 scalekit_client = ScalekitClient( 5 os.environ['SCALEKIT_ENV_URL'], 6 os.environ['SCALEKIT_CLIENT_ID'], 7 os.environ['SCALEKIT_CLIENT_SECRET'], 8 ) 9 10 connector = 'slackmcp' 11 identifier = 'user_123' 12 13 # Read a channel's message history 14 result = scalekit_client.actions.execute_tool( 15 connector=connector, 16 identifier=identifier, 17 tool_name='slackmcp_slack_read_channel', 18 tool_input={'channel_id': 'C01234567'}, 19 ) 20 print(result) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Sleekplan MCP connector > Sleekplan is a customer feedback, feature request, and roadmap management platform. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sleekplanmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Sleekplan MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sleekplanmcp_list_admins', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sleekplanmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Sleekplan MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="sleekplanmcp_list_admins", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update document, survey questions, survey name** — Update a document * **Feedback unlink document from, link document to, tag** — Remove the link between a document and a feedback post * **Meta set feedback** — Add or update custom meta on an existing feedback post * **Version restore document** — Restore an earlier version, replacing the document’s current title, body, type, and tags * **List feedback documents, documents, document versions** — List the documents that inform one feedback post — the thinking behind that request * **Get feedback meta, document version, document** — Read the custom meta key/value pairs attached to a feedback post ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Slite MCP connector > Connect to Slite MCP. Create and manage notes, channels, collections, and comments in Slite from AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'slitemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Slite MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'slitemcp_read_thread', 25 toolInput: { threadId: 'https://example.com/threadId' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "slitemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Slite MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"threadId":"https://example.com/threadId"}, 27 tool_name="slitemcp_read_thread", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update table** — Make a structured edit to an in-document table (a table embedded in a doc’s body) without re-emitting the whole table — add/remove columns or rows, set cell values * **Agent slite** — Invoke Slite Agent on the workspace knowledge base * **Read thread** — Read an AI thread back as question/answer rounds * **Document edit** — Apply many block edits to a single note as one atomic change — insert, replace a range, or remove blocks — instead of calling append-blocks/modify-range/remove-blocks repeatedly * **List-comment-threads records** — List all non-archived comment threads on a note, oldest-first, with full content * **Create-comment-thread records** — Create a new comment thread on a note, optionally anchored to a specific block or highlighted text ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Smartling MCP connector > Connect to Smartling MCP to manage translation projects, jobs, files, and glossaries, and run machine translation and localization workflows from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'smartlingmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Smartling MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'smartlingmcp_smartling_get_available_accounts_for_current_user', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "smartlingmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Smartling MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="smartlingmcp_smartling_get_available_accounts_for_current_user", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update smartling** — Get detailed information about a specific Smartling job by its UID * **Search smartling** — Search translation memory for similar translations in a Smartling project * **Url smartling request upload** — Requests a short-lived URL for uploading a local file, for use with other tools that accept an “upload\_id” parameter (e.g * **Strings smartling remove tags from, smartling remove all tags from, smartling add tags to** — Remove tags from strings in a Smartling project * **Job smartling remove strings from, smartling authorize, smartling add strings to** — Remove strings from an existing Smartling job by their hashcodes * **Issue smartling open or close** — Open or close (resolve) an issue ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SMTP2GO connector > SMTP2GO is a transactional email and SMS delivery platform for developers. Send transactional and bulk email and SMS, manage templates, sender domains... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your SMTP2GO credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'smtp2go' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'smtp2go_view_ip_allow_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "smtp2go" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="smtp2go_view_ip_allow_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List view ip allow, remove ip allow, enable ip allow** — Retrieve the IP addresses on your SMTP2GO account’s IP allow list, along with whether the list is currently enabled * **Webhook view, remove, edit** — Retrieve the configuration of the webhook currently set up on the SMTP2GO account * **Details view template** — Retrieve the full details of a single email template on the SMTP2GO account, identified by its case-sensitive template ID, including its name, subject, HTML body, text body, template variables, tags, and last-updated timestamp * **Suppressions view** — Search and list entries on the SMTP2GO suppression (block) list, with rich filtering by email address, recipient(s), reason(s), suppression type(s), a wildcard string, and a date range, plus fuzzy matching and pagination via continue\_token * **Users view smtp** — Retrieve SMTP users on your SMTP2GO account * **Emails view single sender, view sent, remove scheduled** — List the Single Sender email addresses verified on this SMTP2GO account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SMTP2GO MCP connector > SMTP2GO's MCP server exposes its API documentation and a generic request executor - discover SMTP2GO API endpoints (list-endpoints, get-endpoint... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'smtp2gomcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'smtp2gomcp_get_server_variables', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "smtp2gomcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="smtp2gomcp_get_server_variables", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search endpoints** — Performs a deep search through paths, operations, and parameters to discover relevant SMTP2GO API endpoints * **List endpoints** — Lists all API paths and their HTTP methods with summaries, organized by path * **Get server variables, endpoint** — Gets the server variables for each server within the SMTP2GO OpenAPI spec * **Execute request** — Executes an SMTP2GO API request using a given HAR (HTTP Archive) request object — the method, url, headers, query string, and body describing the call to make ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Snowflake connector > Connect to Snowflake to manage and analyze your data warehouse workloads 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Snowflake credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'snowflake' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Snowflake:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'snowflake_cancel_query', 25 toolInput: { statement_handle: 'YOUR_STATEMENT_HANDLE' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "snowflake" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Snowflake:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"statement_handle":"YOUR_STATEMENT_HANDLE"}, 27 tool_name="snowflake_cancel_query", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Table undrop, drop, clone** — Restore a recently dropped table from Time Travel using the Table REST API (POST /api/v2/databases/{database}/schemas/{schema}/tables/{name}:undrop) * **Schema undrop, drop, alter** — Restore a recently dropped schema from Time Travel using the Schema REST API (POST /api/v2/databases/{database}/schemas/{name}:undrop) * **Database undrop, drop, clone** — Restore a recently dropped Snowflake database from Time Travel using the Database REST API (POST /api/v2/databases/{name}:undrop) * **Warehouse suspend, resume, rename** — Suspend a running Snowflake warehouse, releasing its compute resources (POST /api/v2/warehouses/{name}:suspend) * **User revoke role from, grant role to, drop** — Run REVOKE ROLE `` FROM USER `` via the SQL statements API * **Role revoke privilege from, grant privilege to, drop** — Run REVOKE \[GRANT OPTION FOR] `` ON `` `` FROM ROLE `` \[RESTRICT | CASCADE] via the SQL statements API ## Common workflows [Section titled “Common workflows”](#common-workflows) **Don’t worry about your Snowflake account domain in the path.** Scalekit automatically resolves `{{domain}}` from the connected account’s configuration. For example, a request with `path="/api/v2/statements"` will be sent to `https://myorg-myaccount.snowflakecomputing.com/api/v2/statements` automatically. ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Snowflake Key Pair Auth connector > Connect to Snowflake via Public Private Key Pair to manage and analyze your data warehouse workloads 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'snowflakekeyauth' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'snowflakekeyauth_cancel_query', 19 toolInput: { statement_handle: 'YOUR_STATEMENT_HANDLE' }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "snowflakekeyauth" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"statement_handle":"YOUR_STATEMENT_HANDLE"}, 19 tool_name="snowflakekeyauth_cancel_query", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Table undrop, drop, clone** — Restore a recently dropped table from Time Travel using the Table REST API (POST /api/v2/databases/{database}/schemas/{schema}/tables/{name}:undrop) * **Schema undrop, drop, alter** — Restore a recently dropped schema from Time Travel using the Schema REST API (POST /api/v2/databases/{database}/schemas/{name}:undrop) * **Database undrop, drop, clone** — Restore a recently dropped Snowflake database from Time Travel using the Database REST API (POST /api/v2/databases/{name}:undrop) * **Warehouse suspend, resume, rename** — Suspend a running Snowflake warehouse, releasing its compute resources (POST /api/v2/warehouses/{name}:suspend) * **User revoke role from, grant role to, drop** — Run REVOKE ROLE `` FROM USER `` via the SQL statements API * **Role revoke privilege from, grant privilege to, drop** — Run REVOKE \[GRANT OPTION FOR] `` ON `` `` FROM ROLE `` \[RESTRICT | CASCADE] via the SQL statements API ## Common workflows [Section titled “Common workflows”](#common-workflows) **Don’t worry about your Snowflake account domain in the path.** Scalekit automatically resolves `{{domain}}` from the connected account’s configuration. For example, a request with `path="/api/v2/statements"` will be sent to `https://myorg-myaccount.snowflakecomputing.com/api/v2/statements` automatically. ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Splice MCP connector > Connect to Splice MCP. Search the Splice sample catalog, create and update multi-track stacks, download audio assets, and generate arrangements from text... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'splicemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Splice MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'splicemcp_create_stack', 25 toolInput: { asset_uuid: 'YOUR_ASSET_UUID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "splicemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Splice MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"asset_uuid":"YOUR_ASSET_UUID"}, 27 tool_name="splicemcp_create_stack", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update stack** — Modify an existing stack by adding, removing, or swapping sounds, or by renaming it or changing its BPM * **Stack share, prompt to** — Generate a public shareable URL for an existing stack by its UUID * **Asset download** — Purchase a Splice sample and return a presigned download URL for the audio file * **Sound describe a** — Search the Splice catalog for samples matching a natural language description, with optional BPM and type filters * **Create stack** — Create a multi-track stack from an existing Splice sample, optionally generating a public share URL ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Sportradar MCP connector > Connect to Sportradar MCP. Browse and search sports data API specs, discover endpoints, check coverage, and access guide pages from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sportradarmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Sportradar MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sportradarmcp_fetch', 25 toolInput: { id: 'YOUR_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sportradarmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Sportradar MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"YOUR_ID"}, 27 tool_name="sportradarmcp_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search records** — Search Sportradar guide pages by query and return matching results with titles and excerpts * **Search-endpoints records** — Search through API paths, operations, and parameters to discover relevant endpoints * **List-specs records** — List all available Sportradar OpenAPI specs * **List-endpoints records** — List all API paths and HTTP methods for a spec, organized by path * **Get-endpoint records** — Get detailed information about a specific API endpoint, including security schemes and parameters * **Get-coverage records** — Find the coverage level for a Sportradar Basketball API ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Stack.ai MCP connector > Connect to Stack AI MCP. Build, run, and manage AI workflow projects, search knowledge bases, list integration providers, and inspect execution traces... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'stackaimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Stack.ai MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'stackaimcp_audit_logs_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "stackaimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Stack.ai MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="stackaimcp_audit_logs_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List skills versions, skills, runs** — List a Stack AI skill’s full version history, newest first * **Get skills version, skills, run** — Fetch one historical version of a Stack AI skill’s full detail: instructions, frontmatter, actions, and file manifest * **Validate skills** — Validate a proposed Stack AI skill bundle offline and preview the normalization the write tools would apply * **Update skills** — Publish a new version of a Stack AI skill as a full replacement, from text fields or a file bundle * **Rollback skills** — Restore a prior version of a Stack AI skill’s content by publishing it as a new latest version * **Create skills, files, project** — Create a new Stack AI skill (version 1) from text fields or a file bundle ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Statuspage connector > Connect to Statuspage. Manage status pages, incidents, components, component groups, subscribers, metrics, and page access permissions. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'statuspage' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'statuspage_pages_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "statuspage" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="statuspage_pages_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List pages, users, templates** — Get the list of Statuspage pages accessible to the authenticated API key * **Update user permissions, subscriber, status embed config** — Update a Statuspage organization user’s role permissions * **Get user permissions, subscribers histogram by state, subscribers count** — Retrieve a Statuspage organization user’s permissions, including the per-page roles (page configuration, incident manager, maintenance manager) they have been granted where Role Based Access Control is enabled * **Delete user, page access user metrics, page access user metric** — Delete a user from a Statuspage organization * **Create user, template, subscriber** — Create a new team member (user) in a Statuspage organization, granting them access to manage the organization’s status pages * **Bulk subscribers unsubscribe, subscribers resend confirmation, subscribers reactivate** — Unsubscribe a list of subscribers from a Statuspage status page, optionally filtered by subscriber type and state, or unsubscribe all subscribers (if fewer than 100) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # StoreLeads MCP connector > Connect to StoreLeads MCP to discover, search, and analyze e-commerce stores and their technology stack from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'storeleadsmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'storeleadsmcp_get_platforms', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "storeleadsmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="storeleadsmcp_get_platforms", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search technologies, domains, apps** — Search technologies used by e-commerce stores * **List historical datasets** — List available historical domain snapshots * **Get technology, products for domain, product** — Look up a single technology by name * **Domain detect, company to** — Detect what e-commerce platform a domain is using ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Stripe connector > Connect to Stripe to manage customers, payments, products, subscriptions, invoices, and financial data. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Stripe credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'stripe' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'stripe_get_account_dahlia', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "stripe" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="stripe_get_account_dahlia", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Note void credit** — Marks a previously issued credit note as void * **Update subscription schedule, setup intent dahlia, price dahlia** — Updates an existing subscription schedule, e.g * **Send invoice dahlia** — Manually sends an invoice to the customer’s email out of the normal automatic billing schedule * **Search subscriptions dahlia, products dahlia, prices dahlia** — Search for subscriptions using Stripe’s Search Query Language * **Dahlia reverse payout, resume subscription, mark invoice uncollectible** — Reverses a payout by debiting the destination bank account * **List transfer reversals dahlia, subscription schedules, customer tax ids dahlia** — Lists the reversals belonging to a specific transfer ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Stripe MCP connector > Connect to Stripe MCP. Manage customers, invoices, subscriptions, refunds, disputes, and payments from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'stripemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Stripe MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'stripemcp_list_available_accounts_or_orgs', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "stripemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Stripe MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="stripemcp_list_available_accounts_or_orgs", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Planner stripe implementation** — Stripe payment integration planner * **Write stripe api** — Execute a write (POST/DELETE) Stripe API operation by its operation ID and parameters * **Read stripe api** — Execute a read-only (GET) Stripe API operation by its operation ID and parameters * **Analytics stripe** — Analyze Stripe data (e.g * **Accounts manage stripe** — Returns a URL to the Stripe Dashboard where the user can add accounts, remove accounts, or change permissions for this session * **List available accounts or orgs** — Lists all Stripe accounts available in this session with their stripe\_context and livemode values ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Supabase connector > Connect to the Supabase Management API to manage organizations, projects, database branches, API keys, secrets, custom domains, network restrictions... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Supabase credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'supabase' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Supabase:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'supabase_get_profile', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "supabase" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Supabase:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="supabase_get_profile", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update storage config, realtime config, legacy api keys** — Update a Supabase project’s Storage service configuration: the maximum upload file size in bytes, and feature flags for image transformation, the S3 protocol, and cache purging * **Realtime shutdown** — Forcibly shut down all active Realtime connections for a Supabase project * **Read setup, remove, only query** — \[Beta] Set up a new read replica for a Supabase project in the given region * **Metrics scrape project** — Scrape a project’s infrastructure metrics in Prometheus exposition format (plain text, not JSON) * **Disk modify database** — Modify a Supabase project’s database disk: change its type (gp3 or io2), size in GB, IOPS, or (gp3 only) throughput in MiB/s * **List project addons, jit access, sso provider** — List the billing addons currently applied to a Supabase project, including the active compute instance size, plus every addon option that can be provisioned along with its pricing metadata ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Supabase MCP connector > Connect to Supabase MCP. Manage projects, databases, branches, Edge Functions, migrations, and logs directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'supabasemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Supabase MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'supabasemcp_list_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "supabasemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Supabase MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="supabasemcp_list_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search docs** — Search the Supabase documentation using GraphQL * **Project restore, pause** — Restores a Supabase project * **Branch reset, rebase, merge** — Resets migrations of a development branch * **Query logs** — Runs a custom read-only ClickHouse SQL query against a Supabase project’s unified logs stream, for filtering, aggregating, or joining across log fields more precisely than a simple per-service log dump * **List tables, projects, organizations** — Lists all tables in one or more schemas * **Get publishable keys, project url, project** — Gets all publishable API keys for a project, including legacy anon keys (JWT-based) and modern publishable keys (format: sb\_publishable\_…) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Supadata connector > Connect with Supadata to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Supadata credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'supadata' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'supadata_account_get', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "supadata" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="supadata_account_get", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Batch youtube video, youtube transcript** — Start an asynchronous batch job that fetches metadata for multiple YouTube videos in one call * **Videos youtube playlist, youtube channel** — Retrieve the video IDs contained in a YouTube playlist, in playlist order * **Get youtube batch, web crawl, transcript job** — Check the status of a YouTube batch job (transcripts or video metadata) and retrieve its results once complete * **Start web crawl** — Start an asynchronous crawl job that extracts content from all pages on a website, following internal links up to the given page limit * **Extract records** — Use AI to analyze a video or media URL and extract structured data from it, guided by a natural-language prompt and/or a JSON schema * **Scrape web** — Scrape a web page and return its content as clean Markdown ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Supadata MCP connector > Connect with Supadata MCP to extract transcripts, metadata, and structured content from YouTube, social media, and the web using AI. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'supadatamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Supadata MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'supadatamcp_supadata_check_crawl_status', 25 toolInput: { id: 'YOUR_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "supadatamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Supadata MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"YOUR_ID"}, 27 tool_name="supadatamcp_supadata_check_crawl_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Transcript supadata** — Extract transcript from a video or file URL * **Scrape supadata** — Scrape a single web page and return its content * **Metadata supadata** — Fetch metadata from a media URL (YouTube, TikTok, Instagram, Twitter) * **Map supadata** — Discover URLs on a website * **Extract supadata** — Extract structured data from a video URL using AI * **Crawl supadata** — Create a crawl job to extract content from all pages on a website ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Supermetrics MCP connector > Connect to Supermetrics MCP to query marketing data, discover data sources, manage campaigns, and run analytics across your connected ad and analytics... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Supermetrics MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'supermetricsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Supermetrics MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'supermetricsmcp_get_today', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "supermetricsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Supermetrics MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="supermetricsmcp_get_today", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Guide supermetrics** — Explain what Supermetrics can do for this user, or show what has changed recently * **Team manage user and** — Manage your Supermetrics account: get user profile, license, and team member info, invite new members, get a login link for a data source, or assign users to a subscription * **Dashboards manage** — Upload, retrieve, edit, or view version history for live Supermetrics Studio dashboards that re-query data on each view * **Manage resources** — Open the visual media picker or manage ad creative assets for a supported platform * **Get today, async query results, campaign and resource** — Get the current UTC date and time * **Discovery field, data source, accounts** — List available metrics and dimensions for a specific data source ## Common workflows [Section titled “Common workflows”](#common-workflows) ### Discover available data sources Use `supermetricsmcp_data_source_discovery` to list all marketing and advertising data sources connected to the user’s Supermetrics account. * Node.js ```typescript 1 const sources = await actions.executeTool({ 2 connectionName: 'supermetricsmcp', 3 identifier: 'user_123', 4 toolName: 'supermetricsmcp_data_source_discovery', 5 toolInput: {}, 6 }); 7 console.log(sources); ``` * Python ```python 1 sources = actions.execute_tool( 2 connection_name="supermetricsmcp", 3 identifier="user_123", 4 tool_name="supermetricsmcp_data_source_discovery", 5 tool_input={}, 6 ) 7 print(sources) ``` ### Query marketing analytics data Use `supermetricsmcp_data_query` to pull structured metrics and dimensions from a connected data source. Call `field_discovery` first to find valid field names, and `get_today` to resolve relative date references. * Node.js ```typescript 1 const report = await actions.executeTool({ 2 connectionName: 'supermetricsmcp', 3 identifier: 'user_123', 4 toolName: 'supermetricsmcp_data_query', 5 toolInput: { 6 ds_id: 'GA4', 7 fields: ['Sessions', 'Conversions', 'Date'], 8 date_range_type: 'last_30_days', 9 max_rows: 100, 10 }, 11 }); 12 console.log(report); ``` * Python ```python 1 report = actions.execute_tool( 2 connection_name="supermetricsmcp", 3 identifier="user_123", 4 tool_name="supermetricsmcp_data_query", 5 tool_input={ 6 "ds_id": "GA4", 7 "fields": ["Sessions", "Conversions", "Date"], 8 "date_range_type": "last_30_days", 9 "max_rows": 100, 10 }, 11 ) 12 print(report) ``` ### Create an ad campaign Use `supermetricsmcp_campaign_create` to create a new advertising campaign on a supported platform. Call `accounts_discovery` first to find the correct account ID. * Node.js ```typescript 1 const campaign = await actions.executeTool({ 2 connectionName: 'supermetricsmcp', 3 identifier: 'user_123', 4 toolName: 'supermetricsmcp_campaign_create', 5 toolInput: { 6 ds_id: 'FA', 7 account_id: 'act_123456789', 8 name: 'Q1 Brand Awareness', 9 status: 'PAUSED', 10 budget_amount: '50.00', 11 budget_type: 'DAILY', 12 }, 13 }); 14 console.log(campaign); ``` * Python ```python 1 campaign = actions.execute_tool( 2 connection_name="supermetricsmcp", 3 identifier="user_123", 4 tool_name="supermetricsmcp_campaign_create", 5 tool_input={ 6 "ds_id": "FA", 7 "account_id": "act_123456789", 8 "name": "Q1 Brand Awareness", 9 "status": "PAUSED", 10 "budget_amount": "50.00", 11 "budget_type": "DAILY", 12 }, 13 ) 14 print(campaign) ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # SurveyMonkey MCP connector > Connect to SurveyMonkey to manage surveys, collect responses, and analyze results. Create and update surveys, manage collectors and contacts, and retrieve... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'surveymonkeymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize SurveyMonkey MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'surveymonkeymcp_get_question_types', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "surveymonkeymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize SurveyMonkey MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="surveymonkeymcp_get_question_types", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get response summary, survey, server info** — Get a pre-computed statistical summary of all responses to a survey, with numerically accurate counts, percentages, and human-readable choice labels already resolved for every question * **Update survey** — Update survey properties such as title or nickname * **Search surveys** — Get a paginated list of surveys for the authenticated user * **Questions reorder** — Bulk reorder all questions on a survey page * **Plan generate survey** — Generate an AI-powered survey plan from a natural language description * **Question edit, add** — Edit a single question’s text, required status, answer choices, position, or move it to a different page ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Swagger MCP connector > Connect to Swagger MCP. Create and manage APIs, developer portals, and documentation in SwaggerHub from AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'swaggermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Swagger MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'swaggermcp_swagger_list_organizations', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "swaggermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Swagger MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="swaggermcp_swagger_list_organizations", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Registry swagger scan api standardization from** — Run a standardization scan on an API that already exists in SwaggerHub Registry, identified by organization name, API name, and version * **Portal swagger resolve organization** — Resolve portal details for a Swagger organization in a single step * **Create swagger** — Create a documentation page in a portal product in a single tool call * **Update swagger** — Update a product’s settings within a specific portal * **Api swagger standardize** — Standardize and fix an API definition using AI to ensure compliance with governance policies * **Search swagger** — Search for APIs and Domains in SwaggerHub Registry using the comprehensive /specs endpoint and retrieve metadata including owner, name, description, summary, version, and specification ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Sybill MCP connector > Connect to Sybill. Access AI-generated summaries of sales calls, deals, accounts, and conversations to accelerate B2B revenue workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'sybilmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Sybill MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'sybilmcp_list_accounts', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "sybilmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Sybill MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="sybilmcp_list_accounts", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sybill ask** — Ask Sybill AI about your sales calls, deals, accounts, or contacts * **List conversations, accounts, deals** — List sales conversations with optional filters for date range, meeting type, and attendees * **Get conversation, deal, account** — Get full details of a single conversation including summary, transcript, and recording URLs ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Synapse MCP connector > Connect to the Synapse MCP server (Sage Bionetworks) to explore Synapse entities, annotations, provenance, and project structure, and to search... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'synapsemcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Synapse MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'synapsemcp_get_evaluation', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "synapsemcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Synapse MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="synapsemcp_get_evaluation", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search entity by name, entities by md5, synapse** — Use this when the user has a file name or Synapse entity name (and optionally its parent folder or project) but does not know the Synapse ID — resolves an exact name to its Synapse ID * **List submission statuses, my submissions, my submission bundles** — Use this when the user wants the scoring statuses of every Synapse submission in an Evaluation queue — optionally filtered (SCORED, INVALID, etc.) * **Get wiki page, wiki order hint, wiki history** — Use this when the user wants to read a Synapse wiki page — its markdown content and metadata — attached to a project, folder, or file * **Certified check user** — Use this when the user wants to know whether a Synapse user has passed the certification quiz required for uploading human data * **Id check synapse** — Use this when the user has a string that looks like a Synapse ID (e.g ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Synthesize Bio MCP connector > Connect to Synthesize Bio MCP. Run differential gene expression analysis, resolve sample metadata, and retrieve results and raw counts data from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'synthesizebiomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Synthesize Bio MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'synthesizebiomcp_get_metadata_schema', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "synthesizebiomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Synthesize Bio MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="synthesizebiomcp_get_metadata_schema", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get metadata schema, counts data url, analysis results** — Retrieve the structured-metadata schema used to turn a natural-language experiment description into the sample groups required by resolve\_sample\_metadata * **Metadata resolve sample** — Resolve a natural-language experiment description into structured sample groups using Synthesize Bio’s AI metadata extraction * **Expression analyze gene** — Start a differential gene expression analysis using Synthesize Bio’s AI platform, returning a job ID to track progress ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Tableau connector > Connect to Tableau Cloud or Tableau Server to browse workbooks, views, and data sources, export visualizations, and query underlying data. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Tableau credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'tableau' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'tableau_datasources_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "tableau" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="tableau_datasources_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update workbook, user, schedule** — Update a Tableau workbook’s name, description, owner, project (move it), tab visibility, or certification status * **List workbook permissions, sites, schedules** — Retrieve the capability grants (permissions) defined for a specific Tableau workbook, showing which users and groups can view, edit, or manage it * **Add workbook permissions, project permissions** — Grant a user or group specific capabilities (permissions) on a Tableau workbook, such as Read, Write, or ExportData * **Delete workbook permission, schedule, workbook** — Revoke a single capability grant for a user or group on a Tableau workbook * **Get view pdf, view image, view data** — Render a Tableau view as a PDF document * **Create schedule, project, group** — Create a new server schedule for running extract refreshes, subscriptions, or flow tasks on a recurring basis ## Common workflows [Section titled “Common workflows”](#common-workflows) The **site ID** (site LUID) is resolved automatically from the connected account after sign-in. You do not pass `site_id` to tool calls. For proxy API calls that require a site ID in the URL path, call `tableau_session_get` once to retrieve it. ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most Tableau tools require one or more resource LUIDs. The **site ID is resolved automatically** by Scalekit after sign-in — you do not pass it to tool calls. Always fetch other IDs from the API — never guess or hard-code them. | Resource | Tool to get ID | Field in response | | -------------------- | ----------------------------------------------------- | ----------------------------- | | Workbook ID | `tableau_workbooks_list` or `tableau_workbook_search` | `workbooks.workbook[].id` | | View ID | `tableau_views_list` or `tableau_workbook_views_list` | `views.view[].id` | | Data Source ID | `tableau_datasources_list` | `datasources.datasource[].id` | | Project ID | `tableau_projects_list` | `projects.project[].id` | | User ID | `tableau_users_list` | `users.user[].id` | | Group ID | `tableau_groups_list` | `groups.group[].id` | | Job ID | `tableau_job_get` (from background job operations) | `job.id` | | Site ID (proxy only) | `tableau_session_get` | `session.site.id` | **Recommended start sequence for any agent session:** ```text 1 1. tableau_workbooks_list → discover workbooks 2 2. tableau_workbook_views_list → discover views within a workbook 3 3. tableau_datasources_list → discover data sources ``` ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Tactiq MCP connector > Tactiq captures and transcribes meetings in real time, turning conversations into AI-generated notes, summaries, and action items. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'tactiqmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Tactiq MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'tactiqmcp_list_recent_meetings', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "tactiqmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Tactiq MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="tactiqmcp_list_recent_meetings", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get transcript excerpts, transcript, meeting artifact** — Find the verbatim transcript excerpts of a meeting that are relevant to a question — what exactly was said, by whom, and when * **Excerpt expand transcript** — Read the conversation immediately around an excerpt returned by get\_transcript\_excerpts — the question it answered, the reply it drew * **Search meetings** — Search the user’s accessible meetings (owned + shared + team + space) by topic, participants, or date range * **List recent meetings, meeting artifacts** — List the user’s most recent accessible meetings (owned + shared + team + space), sorted newest first ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Tally MCP connector > Connect to Tally MCP. Create and edit forms, manage submissions, and update styling and logic in your Tally workspace from AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'tallymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Tally MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'tallymcp_list_blocks', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "tallymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Tally MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="tallymcp_list_blocks", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search documentation** — Answer-only search of the Tally Help Center for explicit documentation or product-knowledge questions: how Tally works, whether a capability exists, supported features, limits, or docs links * **Update text, styling, settings** — Update the HTML text content of blocks in the form * **Title set form** — Set or update the form title that appears at the top of the form * **Layout set column** — Organize blocks into a side-by-side column layout * **Form save, load** — Save the current form changes and optionally publish or unpublish the form * **Questions reposition, remove** — Move or swap questions using a command (move, swap) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Tango MCP connector > Connect to Tango MCP by makegov to search federal contracts, opportunities, vehicles, organizations, and protests, and pull competitive... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Tango MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'tangomcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'tangomcp_search', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "tangomcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="tangomcp_search", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search opportunities** — Search open federal pre-award procurement records — SAM.gov opportunities, procurement forecasts, DLA DIBBS RFQs/RFPs, and SBIR/STTR topics and solicitations * **Resolve records** — Find entities, vehicles, NAICS/PSC codes, GSA MAS SINs, contracts, opportunities, IDVs, OTAs, subawards, organizations, and GAO bid protests matching a search query * **Get details** — Get detailed information about a single item — entity, contract, IDV, vehicle, opportunity, OTA, OTIDV, organization, protest, SIN, GSA eLibrary contract, IT investment, NAICS/PSC code, budget account, DIBBS RFQ/RFP/award, SAM exclusion, or SBIR topic/solicitation * **Fetch api docs** — Fetch detailed Tango API documentation for a specific section ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Tavily MCP connector > Connect to Tavily MCP. Search the web, crawl websites, extract content, map site structure, and run deep research using Tavily's AI-powered search API. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'tavilymcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Tavily MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'tavilymcp_tavily_search', 25 toolInput: { query: 'YOUR_QUERY' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "tavilymcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Tavily MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"YOUR_QUERY"}, 27 tool_name="tavilymcp_tavily_search", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search tavily** — Search the web for current information and return snippets with source URLs * **Research tavily** — Run comprehensive multi-source research on a topic or question * **Map tavily** — Map a website’s URL structure starting from a base URL * **Extract tavily** — Extract raw content from one or more URLs in markdown or plain text format * **Crawl tavily** — Crawl a website from a starting URL and extract page content with configurable depth and breadth ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Telnyx MCP connector > Telnyx is a communications platform for voice, messaging, and AI. This MCP connector lets AI agents manage phone numbers, send SMS and MMS, place and... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'telnyxmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Telnyx MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'telnyxmcp_list_api_endpoints', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "telnyxmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Telnyx MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="telnyxmcp_list_api_endpoints", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Monitor open voice** — Open the Telnyx Voice Monitor MCP App for observing and troubleshooting voice traffic * **Explorer open usage cost** — Open the Telnyx Usage & Cost Explorer MCP App for usage and cost analysis * **Intelligence open number** — Open the Telnyx Number Intelligence MCP App for phone number lookup, validation, and enrichment workflows * **List api endpoints** — List or search all endpoints in the Telnyx API * **Endpoint invoke api** — Invoke any Telnyx API endpoint by name * **Get api endpoint schema** — Get the JSON schema for a named Telnyx API endpoint ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Testdino MCP connector > TestDino is a Playwright test reporting and analytics platform that centralizes test data, detects flaky tests, and provides AI-powered debugging via MCP... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'testidinomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Testdino MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'testidinomcp_get_trace_analysis', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "testidinomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Testdino MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="testidinomcp_get_trace_analysis", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Fix verify** — Check whether a fix actually held for one test, against the run you saw when you proposed it * **Get trace analysis, run error clusters, integration status** — Debug a failing Playwright test from its trace.zip using the Playwright agent CLI (npx playwright trace …, Playwright 1.59+) * **Create external issue, session, release** — Create a provider issue/task/item linked to a TestDino entity * **Integration connect** — Start the provider OAuth/connect flow for a TestDino project * **Update session, run test case, release** — Modify an existing exploratory session * **Report submit audit** — FINAL STEP of the TestDino Playwright audit flow — submits a completed audit report ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # TickTick MCP connector > Connect to TickTick MCP. Manage tasks, projects, habits, and focus sessions in your TickTick account from AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'ticktickmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize TickTick MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'ticktickmcp_get_user_preference', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "ticktickmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize TickTick MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="ticktickmcp_get_user_preference", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Task unassign, assign, move** — Remove the assignee from a task in a shared project * **List project members, undone tasks by time query, undone tasks by date** — List members of a shared project * **Checkins upsert habit** — Create or update check-in records for a habit by habitId * **Update task, project group, project** — Update an existing task’s fields * **Search task** — Search tasks by keyword and return matching taskId, title, and URL * **Get user preference, task in project, task by id** — Get user preferences including timezone and display settings ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Tinyfish MCP connector > Connect to Tinyfish MCP. Run browser-based web automations, fetch page content, and search the web using a real cloud Chrome browser. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'tinyfishmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Tinyfish MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'tinyfishmcp_get_wallet', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "tinyfishmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Tinyfish MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="tinyfishmcp_get_wallet", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Step guide next** — Returns the next interactive TinyFish onboarding step based on the user’s real usage * **Get wallet, steps, search usage** — Read-only * **Session close browser** — Only use when the user explicitly wants to stop or close a remote browser session * **Search records** — Search the web and return structured results with titles, snippets, and URLs * **Run web automation async, web automation, discover** — Start a single web automation in the background and return the run ID immediately without waiting for completion * **Status poll, batch** — Return the current status, step count, and progress for an automation run ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Todoist MCP connector > Connect to Todoist MCP. Manage tasks, projects, sections, labels, filters, goals, and reminders from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'todoistmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Todoist MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'todoistmcp_fetch', 25 toolInput: { id: 'YOUR_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "todoistmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Todoist MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"id":"YOUR_ID"}, 27 tool_name="todoistmcp_fetch", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Import-project-template records** — Import a template into an existing project, adding its tasks, sections and comments to whatever is already there * **Export-project-template records** — Export an existing project as a Todoist template, either as CSV content or as a shareable URL * **View-attachment records** — View a file attachment from a Todoist comment * **User-info records** — Get comprehensive user information including user ID, full name, email, timezone with current local time, week start day preferences, current week dates, daily/weekly goal progress, and user plan (Free/Pro/Business) * **Update-tasks records** — Update existing tasks including content, dates, priorities, and assignments * **Update-sections records** — Update multiple existing sections with new values ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # TopCounsel MCP connector > Connect to TopCounsel by The L Suite to search, shortlist, and compare peer-vetted outside counsel recommendations grounded in firsthand feedback from... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'topcounselmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize TopCounsel MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'topcounselmcp_find_outside_counsel', 25 toolInput: { query: 'https://example.com/query' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "topcounselmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize TopCounsel MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"query":"https://example.com/query"}, 27 tool_name="topcounselmcp_find_outside_counsel", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Counsel find outside** — Find the right outside counsel for an inhouse counsel looking to hire for a specific matter ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Trello connector > Connect to Trello. Manage boards, cards, lists, and team collaboration workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Trello credentials with Scalekit so it handles the token lifecycle. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update list, label, checklist item** — Rename, reposition, or archive/unarchive a Trello list * **Search records** — Global keyword search across Trello boards, cards, members, and organizations that the authenticated user can access * **Card remove member from, remove label from, add member to** — Remove a member from a Trello card * **List my boards** — List the boards the authenticated user belongs to * **Get webhook, current member, checklist** — Get a Trello webhook’s current details and status by ID * **Delete webhook, label, comment** — Permanently delete a Trello webhook by its ID, stopping any further callbacks ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Trello MCP connector > Connect to Trello's official MCP server to manage boards, cards, lists, and team collaboration workflows directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'trellomcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Trello MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'trellomcp_trello_read_list', 25 toolInput: { action: 'YOUR_ACTION' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "trellomcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Trello MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"action":"YOUR_ACTION"}, 27 tool_name="trellomcp_trello_read_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Planner trello write** — Create Trello Planner calendar events and manage card-event links * **List trello write** — Create, update, archive, or move a Trello list * **Inbox trello write** — Write Trello Inbox cards * **Checklist trello write** — Write Trello checklists and their check items * **Card trello write** — Create, update, move, archive, mark Trello cards done, or manage labels on cards * **Board trello write** — Create Trello boards ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Twelve Data MCP connector > Connect to Twelve Data MCP for real-time and historical financial market data, including stock, forex, crypto, and ETF prices, technical indicators... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'twelvedatamcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Twelve Data MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'twelvedatamcp_auth_status', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "twelvedatamcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Twelve Data MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="twelvedatamcp_auth_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Login oauth** — Authenticate with Twelve Data via OAuth 2.0 * **Configure oauth** — Save Twelve Data OAuth credentials to local config so they can be used by oauth\_login * **Status auth** — Show current authentication state, useful for debugging * **Search symbol** — Search for financial instruments by name or partial ticker, or find cross-listings * **Get time series, technical indicator, statistics** — Get historical OHLCV (Open, High, Low, Close, Volume) time series data * **Conversion currency** — Get exchange rate or convert an amount between currencies (fiat or crypto) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Twilio connector > Connect to Twilio to send SMS/MMS messages, make voice calls, verify phone numbers with OTP, manage phone numbers, and access usage records. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Twilio credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update verify service, verification, phone number** — Update settings of an existing Twilio Verify service, such as its code length or friendly name * **Create verification, subaccount, queue** — Start a phone or email verification by sending a one-time code via Twilio Verify * **Check verification** — Check a one-time verification code entered by a user against a Twilio Verify service * **List queues, applications, accounts** — List call queues on the account, used with TwiML’s `` and `` verbs * **Delete phone number, conference participant, verify service** — Release (delete) an incoming phone number from your Twilio account * **Number lookup phone** — Look up information about a phone number, such as formatting, carrier, line type, and caller name, using Twilio Lookup ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Twitter / X connector > Connect to Twitter. Read and write Tweets, read users, manage follows, bookmarks, etc. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Twitter / X credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'twitter' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'twitter_activity_subscriptions_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "twitter" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="twitter_activity_subscriptions_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search users, communities, full archive** — Searches for users matching the provided query string, ranked by relevance * **Stream users compliance, tweets compliance, likes compliance** — Streams real-time compliance events (account deletions, deactivations, username changes, suspensions) for Users so downstream systems can stay in sync * **Get user reposts of me, user posts, user mentions** — Retrieves the most recent Posts that repost content from the authenticated user * **Create user bookmark folder, media subtitles, media metadata** — Creates a new Bookmark folder for the authenticated user * **Delete media subtitles, activity subscription, post** — Removes a subtitle (closed caption) track of a specific language from a video * **Lookup media, media batch, users** — Retrieves details for a single piece of media by its media key ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Twitter / X connector > Connect to Twitter using an App-Only Bearer Token to access public, read-only, and application-level endpoints — search, compliance jobs and streams... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Twitter / X credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'twitterbearer' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'twitterbearer_activity_subscriptions_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "twitterbearer" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="twitterbearer_activity_subscriptions_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Username users lookup by, user lookup by** — Retrieves detailed information for 1 to 100 Twitter users by their usernames (each 1-15 alphanumeric characters/underscores) * **Lookup users, user, posts** — Retrieves detailed information for specified X (formerly Twitter) user IDs * **Stream users compliance, tweets compliance, tweet label** — Streams real-time compliance events (account deletions, deactivations, username changes, suspensions) for Users so downstream systems can stay in sync * **Get user posts, user owned lists, user mentions** — Retrieves a collection of Posts (Tweets) authored by the specified user, most recent first * **List user, timeline get, members get** — Retrieves all Twitter Lists a specified user is a member of, including public Lists and private Lists the authenticated user is authorized to view * **Search spaces, recent, full archive** — Searches for Twitter Spaces by a textual query ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Twitter / X connector > Connect to Twitter using OAuth 2.0 (Authorization Code with PKCE) to read and write Tweets on behalf of the authenticated user, manage users, follows... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Twitter / X credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'twitteroauth' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Twitter / X:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'twitteroauth_activity_subscriptions_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "twitteroauth" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Twitter / X:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="twitteroauth_activity_subscriptions_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search users, spaces, recent** — Searches for users matching the provided query string, ranked by relevance * **Username users lookup by, user lookup by** — Retrieves detailed information for 1 to 100 Twitter users by their usernames (each 1-15 alphanumeric characters/underscores) * **Lookup users, user, posts** — Retrieves detailed information for specified X (formerly Twitter) user IDs * **Unmute user** — Unmutes a target user for the authenticated user, allowing them to see Tweets and notifications from the target user again * **Unfollow user** — Allows the authenticated user to unfollow an existing Twitter user, which removes the follow relationship * **Get user timeline, user reposts of me, user posts** — Retrieves the home timeline (reverse chronological feed) for the authenticated Twitter user ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Typeform MCP connector > Connect to Typeform MCP to create and manage forms, read responses, and manage workspaces, contacts, and webhooks directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'typeformmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Typeform MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'typeformmcp_contacts_public_delete_contacts_list', 25 toolInput: { account_id: 'YOUR_ACCOUNT_ID', list_id: 'YOUR_LIST_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "typeformmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Typeform MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"account_id":"YOUR_ACCOUNT_ID","list_id":"YOUR_LIST_ID"}, 27 tool_name="typeformmcp_contacts_public_delete_contacts_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Feedback submit** — Call this any time a task cannot be completed as literally requested — missing feature, false premise, permission error, API failure, etc * **Toplist insights public** — ## What this tool does Ranks groups of rows by a measure — e.g * **Timeseries insights public** — ## What this tool does Computes measures bucketed over time for a single field or an entire dataset * **Aggregate insights public** — ## What this tool does Computes aggregate measures (counts, averages, sums, NPS scores, and more) for a single field or an entire dataset * **Patch forms public validate** — Validate a batch of patch operations against a form draft without persisting anything * **Update forms public, automations public** — Update the form title ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Upstream MCP connector > Connect to Upstream MCP to access AI-assistant tools and workflows, including inbox management, directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Upstream MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'upstreammcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'upstreammcp_get_inbox_split_threads', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "upstreammcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="upstreammcp_get_inbox_split_threads", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update settings, rule, inbox split** — Update user settings like auto-draft configuration, theme, and notification preferences * **Threads trash, star** — Move threads to trash or restore them * **Thread snooze, save draft, reply to** — Snooze a thread until a specific date/time * **Search inbox** — Search across all inbox threads by keyword or phrase * **Reply save draft** — Save a draft reply in an existing thread without sending it * **Read thread comments, thread, mark** — Read internal team comments on a thread (not visible to external recipients) ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # v0 MCP connector > Connect to v0 by Vercel to generate and iterate on web app UIs from natural language. Create chats, send follow-up messages, and inspect v0 Platform chats... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your v0 MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'v0mcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'v0mcp_findchats', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "v0mcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="v0mcp_findchats", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sendchatmessage records** — Send a new message to an existing chat using the v0 Platform API * **Getuser records** — Get user information using the v0 Platform API * **Getchat records** — Get a specific chat by ID using the v0 Platform API * **Findchats records** — Find all chats using the v0 Platform API * **Createchat records** — Create a new chat using the v0 Platform API ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Vapi MCP connector > Vapi is an AI-powered voice platform for building, testing, and deploying voice AI agents. This MCP connector enables AI agents to manage Vapi assistants... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Vapi MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'vapimcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'vapimcp_list_assistants', 19 toolInput: { rationale: 'YOUR_RATIONALE' }, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "vapimcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={"rationale":"YOUR_RATIONALE"}, 19 tool_name="vapimcp_list_assistants", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tool, assistant** — Updates an existing Vapi tool’s configuration * **List tools, phone numbers, calls** — Lists all Vapi tools configured in the account * **Get tool, phone number, call** — Retrieves the full configuration of a specific Vapi tool by ID, including its type (SMS, transfer call, function, or API request) and associated settings * **Create tool, call, assistant** — Creates a new Vapi tool that can be attached to assistants ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Vercel connector > Connect to Vercel. Access user profile, teams, projects, deployments, and environment settings. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Vercel credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'vercel' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Vercel:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'vercel_aliases_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "vercel" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Vercel:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="vercel_aliases_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update team member, drain, domain** — Change a Vercel team member’s role, or confirm an unconfirmed member’s request to join the team * **Create sandbox, drain, blob store** — Creates a Vercel Sandbox — an ephemeral, isolated Linux microVM for running untrusted or AI-generated code * **Unpause project** — Resume a paused Vercel project by its project ID * **Rollback project** — Points a Vercel project’s production traffic back to a previous production deployment * **Pause project** — Pause a Vercel project by its project ID * **List project members, project checks, feature flags** — Returns the members of a specific Vercel project, including their computed project role ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Vercel MCP connector > Connect to Vercel MCP to manage deployments, projects, domains, environment variables, and team resources directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Vercel MCP credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'vercelmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Vercel MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'vercelmcp_deploytovercel', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "vercelmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Vercel MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="vercelmcp_deploytovercel", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Updateprojectdeploymentprotection records** — Enable or disable password protection, Vercel Authentication, and Trusted IPs for a Vercel project * **Listagentruns records** — List Agent Runs for a project * **Listagentrunprojects records** — List projects that have Agent Runs, with counts * **Getwebanalytics records** — Query Web Analytics visits or custom events for a project, as a total count or aggregated by dimension * **Getruntimeerrors records** — Get grouped runtime error clusters for a project (error name, occurrence count, affected routes, sample messages, first/last seen) * **Getpurchasequote records** — Get a signed price quote for a Vercel Pro upgrade, credits top-up, add-on, or domain purchase, before executing it ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Vibe Prospecting MCP connector > Connect to Vibe Prospecting by Explorium to build B2B lead lists, research companies and prospects, enrich contacts, and personalize outreach from your AI... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'vibeprospectingmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Vibe Prospecting MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'vibeprospectingmcp_get_dataset', 25 toolInput: { tool_reasoning: 'YOUR_TOOL_REASONING' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "vibeprospectingmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Vibe Prospecting MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"tool_reasoning":"YOUR_TOOL_REASONING"}, 27 tool_name="vibeprospectingmcp_get_dataset", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sample show** — Present the final sample rows to the user from a fetch, enrich, or events exploration table * **Plans show pricing** — Show Vibe Prospecting credit package pricing in an interactive widget * **Prospects match, enrich** — Match specific individuals to get their Explorium prospect IDs * **Business match, enrich** — Get the Explorium business IDs from business name and/or domain in bulk * **Get dataset** — Load a previously exported dataset or list into a session for further analysis, prospecting, or exclusion — or list the user’s most recent datasets * **Fetch prospects events, entities statistics, entities** — Retrieves prospect-related events (role changes, company changes, job anniversaries) from the Explorium API in bulk ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Vimeo connector > Connect to Vimeo API v3.4. Upload and manage videos, organize content into showcases and folders, manage channels, handle comments, likes, and webhooks. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Vimeo credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'vimeo' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Vimeo:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'vimeo_categories_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "vimeo" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Vimeo:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="vimeo_categories_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Unlike video** — Remove the authenticated user’s like from a Vimeo video * **List video texttracks, video pictures, video likes** — List the caption/subtitle text tracks on a Vimeo video * **Delete video texttrack, group, folder** — Remove a caption/subtitle text track from a Vimeo video * **Create video texttrack, video picture, video** — Add a caption/subtitle text track resource to a Vimeo video, specifying its language, name, and type * **Add video tags, group video, showcase video** — Add one or more tags to a Vimeo video in a single batch call * **Remove video tag** — Remove a specific tag from a Vimeo video ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Webflow MCP connector > Connect to Webflow. Build and manage websites, pages, components, styles, assets, CMS collections, and site settings through the Webflow Designer and Data... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'webflowmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Webflow MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'webflowmcp_get_asset_preview', 25 toolInput: { asset_id: 'YOUR_ASSET_ID', context: 'YOUR_CONTEXT' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "webflowmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Webflow MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"asset_id":"YOUR_ASSET_ID","context":"YOUR_CONTEXT"}, 27 tool_name="webflowmcp_get_asset_preview", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get asset preview, more tools, image preview** — Get an image preview of a site asset by its asset ID * **Tool designer, data variable, data style** — Interact with the user’s live Webflow Designer session — select an element on the canvas or read which element is currently selected, navigate the canvas between pages and component canvases, switch to or read the current page, list a page’s branches, read the current branch ID, parent page ID, and Designer mode, enter, exit, or inspect the current component view, and read all breakpoints (media queries) configured for the site * **Builder data whtml, data element, data component** — Data Tool - WHTML builder to insert elements from HTML and CSS strings on a page via the public-mcp headless surface * **Ai ask webflow** — Ask Webflow AI any question about the Webflow API and get a direct answer ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Weflow connector > Connect to Weflow's Public API to read call and meeting recordings and their conversation intelligence data — transcripts, comments, clips, interaction... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'weflow' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'weflow_recordings_list', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "weflow" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="weflow_recordings_list", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List summary templates, recordings, recording trackers** — List the AI summary templates available for the company * **Get recording video, recording transcript, recording summary** — Get pre-signed URLs to stream or download a recording’s video ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Whimsical MCP connector > Connect to Whimsical MCP. Create and edit flowcharts, mind maps, wireframes, and docs, and manage boards, comments, and workspaces from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'whimsicalmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Whimsical MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'whimsicalmcp_list_workspaces', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "whimsicalmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Whimsical MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="whimsicalmcp_list_workspaces", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Get theme data, board items** — Fetch the board theme’s dark color map for Whimbed rendering in the widget * **Edit wireframe, comment** — Reflow or edit Whimsical wireframe elements using operations or a flexbox layout tree * **Search records** — Search workspace files and content by name or full-text query * **List workspaces** — List all workspaces the authenticated user belongs to, including team IDs and member roles * **To how** — Look up Whimsical-specific syntax, examples, and guides for creating diagrams and wireframes * **Wireframe generate** — Generate a Whimsical wireframe with flexbox layout using containers, buttons, inputs, and other UI elements ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Whop MCP connector > Whop is a platform for selling digital products, memberships, and communities. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'whopmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Whop MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'whopmcp_list_api_endpoints', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "whopmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Whop MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="whopmcp_list_api_endpoints", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Search docs** — Search for documentation for how to use the client to interact with the API * **List api endpoints** — List or search for all endpoints in the Whop TypeScript API * **Endpoint invoke api** — Invoke an endpoint in the Whop TypeScript API * **Get api endpoint schema** — Get the schema for an endpoint in the Whop TypeScript API ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Windsor.ai MCP connector > Connect to Windsor.ai MCP to query unified marketing and business data pulled from 350+ connected sources, discover available fields and connectors... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'windsoraimcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Windsor.ai MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'windsoraimcp_get_connectors', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "windsoraimcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Windsor.ai MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="windsoraimcp_get_connectors", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List actions** — Windsor.ai: List a connector’s write actions with their param JSON schemas * **Get windsor login url, subscription url, options** — Windsor.ai: Get a URL into the Windsor.ai dashboard * **Execute action** — Windsor.ai: Execute a write action on a connector account * **Create destination task, custom field** — Windsor.ai: Create a scheduled export of connector data to a destination * **Windsor contact** — Windsor.ai: Send feedback, a support request, or a feature request ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Wix MCP connector > Connect to Wix MCP. Build and manage Wix sites, call REST APIs, search documentation, upload media, and suggest domains from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'wixmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Wix MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'wixmcp_createwixbusinessguide', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "wixmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Wix MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="wixmcp_createwixbusinessguide", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Searchsitetemplates records** — Search the Wix template gallery (Harmony or Studio) by keyword and return matching templates * **Url import claude design from** — Import a design into Wix from a publicly fetchable URL * **Getsitecontext records** — Fetch deep context for a specific Wix site (ID, URL, publish status, plan, properties, and installed apps) as structured markdown * **Createsitefromtemplate records** — Create a Wix site from a specific template by templateId, publish it when possible, and return links to the editor and the published site * **Wixsitebuilder records** — Create or build a new Wix site using AI, returning a job ID to track the creation progress * **Wixreadme records** — Read the Wix MCP README for guidance on how to use the available Wix tools effectively ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # WordPress MCP connector > Connect to WordPress.com's official MCP server to manage posts, pages, comments, media, and site settings directly from your AI workflows. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'wordpressmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize WordPress MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'wordpressmcp_wpcom_ai_agent_sites_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "wordpressmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize WordPress MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="wordpressmcp_wpcom_ai_agent_sites_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Sites wpcom user** — List the authenticated user’s accessible sites across WordPress.com and self-hosted Jetpack-connected sites * **List wpcom plans, wpcom ai agent sites** — Use this to help users select or upgrade WordPress.com hosting * **Management wpcom mcp user, wpcom mcp plugin** — Manage site collaborators on a WordPress.com site * **Context wpcom mcp site editor** — Query site design context * **Editing wpcom mcp site** — Read and modify site structure: templates, template parts, navigation menus (classic and block), global styles, and installed themes * **Site wpcom mcp** — Manage site-level settings and infrastructure for a WordPress.com site — not content (use wpcom-mcp-content-authoring for posts, pages, media) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Xero connector > Connect to Xero. Manage accounting, invoices, contacts, payments, bank transactions, and financial workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Xero credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'xero' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Xero:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'xero_accounts_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "xero" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Xero:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="xero_accounts_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Update tracking option, bank transaction, tracking category** — Update a specific option for a specific tracking category in Xero * **Delete tracking option, tracking category, item** — Delete a specific option for a specific tracking category in Xero * **Get tracking category, tax rate, report by id** — Retrieve a specific tracking category and its options using a unique tracking category ID * **Create tracking category, repeating invoice, payment** — Create a new tracking category in Xero * **List reports, journals, invoice attachments** — Retrieve a list of the organisation’s available ad-hoc reports, each with a unique ReportID needed to fetch its contents * **Summary report budget, report executive, report bank** — Retrieve the Budget Summary report for a Xero organisation ## Common workflows [Section titled “Common workflows”](#common-workflows) Contact field must be a JSON string The `Contact` parameter in `xero_invoice_create`, `xero_credit_note_create`, `xero_purchase_order_create`, and `xero_quote_create` must be passed as a JSON **string**, not an object: `'{"ContactID": "abc123..."}'`. Pass the result of `JSON.stringify({ContactID: id})` in Node.js or `json.dumps({"ContactID": id})` in Python. ## Common patterns [Section titled “Common patterns”](#common-patterns) ### Void (delete) an invoice `xero_invoice_delete` voids an invoice by setting its status to `VOIDED`. Xero only allows voiding invoices that are in `AUTHORISED` status — calling it on a `DRAFT` invoice returns a validation error. The correct sequence is: 1. Authorise the invoice with `xero_invoice_update`, passing `Status: "AUTHORISED"` and a `DueDate`. 2. Call `xero_invoice_delete` with the same `invoice_id`. ### Pass Contact and LineItems correctly Several tools (`xero_invoice_create`, `xero_credit_note_create`, `xero_purchase_order_create`, `xero_quote_create`) take a `Contact` field and a `LineItems` field. * `Contact` — pass as a **JSON string**: `'{"ContactID": "abc123..."}'` * `LineItems` — pass as a **JSON array** (not a string): `[{"Description": "...", "Quantity": 1, "UnitAmount": 100, "AccountCode": "200"}]` Include `AccountCode` in each line item whenever the invoice may later be authorised or voided. ### Quotes require a Date `xero_quote_create` and `xero_quote_update` both require a `Date` field (ISO 8601, e.g. `"2026-04-29"`). Xero returns a validation error `"Date cannot be empty"` without it. `xero_quote_update` also requires `Contact` (JSON string) in addition to `Date`. ### Aged reports require a contactID `xero_report_aged_payables` and `xero_report_aged_receivables` require a `contactID` parameter. The other five report tools (`xero_report_balance_sheet`, `xero_report_profit_and_loss`, `xero_report_trial_balance`, `xero_report_bank_summary`, `xero_report_executive_summary`) require no inputs beyond the auto-injected tenant ID. ### Update an item `xero_item_update` requires `Code` in the request body (in addition to `item_id` in the path). Pass the item’s existing code or a new one — Xero uses it to identify the item being updated. ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # You.com MCP connector > Connect to You.com MCP. Search the web, research topics with cited sources, and extract full page content using You.com's AI-powered search and research... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your You.com MCP credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. 4. ### Make your first call [Section titled “Make your first call”](#make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'youmcp' 12 const identifier = 'user_123' 13 14 // Make your first call 15 const result = await actions.executeTool({ 16 connector, 17 identifier, 18 toolName: 'youmcp_you-balance', 19 toolInput: {}, 20 }) 21 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "youmcp" 14 identifier = "user_123" 15 16 # Make your first call 17 result = actions.execute_tool( 18 tool_input={}, 19 tool_name="youmcp_you-balance", 20 connection_name=connection_name, 21 identifier=identifier, 22 ) 23 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **You-discover records** — Discover AI agents, MCP servers, A2A agents, and skills via ARD Agent Finder services * **You-balance records** — Get the remaining credit balance for the billing entity associated with your You.com API key * **You-answer records** — Fast live-web answer generation returning one synthesized answer with verified inline citations, citation excerpts, and supporting web results * **You-search records** — Search the web and news using You.com * **You-research records** — Research a topic in depth using You.com’s AI * **You-contents records** — Extract content from one or more web pages in markdown, HTML, or structured metadata format ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # YouTube connector > Connect to YouTube to access channel details, analytics, and upload or manage videos via OAuth 2.0 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your YouTube credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'youtube' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize YouTube:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'youtube_analytics_groups_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "youtube" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize YouTube:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="youtube_analytics_groups_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List live streams, live broadcasts, reporting** — List video streams owned by the authenticated user’s YouTube channel * **Insert live streams, live broadcasts, comments** — Create a new YouTube live stream, representing the ingestion endpoint that receives encoder video/audio data * **Transition live broadcasts** — Change the status of a YouTube live broadcast, driving it through its lifecycle * **Bind live broadcasts** — Bind a YouTube live broadcast to a video stream so the broadcast will show that stream’s video once it goes live, or remove an existing binding by omitting stream\_id * **Update comments, videos, analytics groups** — Edit the text of an existing YouTube comment or reply that you have permission to modify * **Status comments set moderation** — Set the moderation status of a comment on a video or channel you own or moderate — approve it, reject it, or hold it for review ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Zapier MCP connector > Connect to Zapier MCP to automate workflows and integrate with thousands of apps directly from your AI agent. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zapiermcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Zapier MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zapiermcp_get_configuration_url', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zapiermcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Zapier MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="zapiermcp_get_configuration_url", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Execute actions across 8,000+ apps** — run read (search/retrieve) and write (create/modify) actions in any app connected to Zapier * **Discover and enable app actions** — search Zapier’s catalog for any app, enable its actions on this MCP server, and disable them when no longer needed * **Auto-provision from existing connections** — automatically set up the MCP server based on the user’s already-connected Zapier accounts * **Manage Zapier Skills** — create, retrieve, update, and delete named reusable workflow documents that define how to accomplish multi-step tasks * **List enabled actions** — inspect which apps and action keys are currently active so the agent always uses correct, up-to-date identifiers * **Get configuration URL** — surface the Zapier MCP configuration page so users can add, edit, or remove connected apps and actions ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Zendesk connector > Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Zendesk credentials with Scalekit so it can authenticate requests on your behalf. You do this once per environment. ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Delete theme, webhook, view** — Delete a Guide theme by its ID * **List themes, webhooks, view tickets** — List the Guide themes installed on the account, optionally filtered by brand * **Publish theme** — Publish a Guide theme, making it the live theme shown to end users in the Help Center * **Get theme, webhook, view** — Retrieve a single Guide theme by its ID * **Update webhook, view, user** — Update an existing webhook’s configuration * **Create webhook, view, user identity** — Create a new webhook to receive Zendesk event notifications at a callback URL ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Zendesk (OAUTH) connector > Connect to Zendesk. Manage customer support tickets, users, organizations, and help desk operations 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Zendesk (OAUTH) credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zendeskoauth' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Zendesk (OAUTH):', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zendeskoauth_automations_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zendeskoauth" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Zendesk (OAUTH):", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="zendeskoauth_automations_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Delete theme, webhook, view** — Delete a Guide theme by its ID * **List themes, webhooks, view tickets** — List the Guide themes installed on the account, optionally filtered by brand * **Publish theme** — Publish a Guide theme, making it the live theme shown to end users in the Help Center * **Get theme, webhook, view** — Retrieve a single Guide theme by its ID * **Update webhook, view, user** — Update an existing webhook’s configuration * **Create webhook, view, user identity** — Create a new webhook to receive Zendesk event notifications at a callback URL ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ZenRows MCP connector > Connect to ZenRows MCP. Scrape any webpage with anti-bot bypass, render JavaScript-heavy sites, and automate browsers through ZenRows' cloud... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zenrowsmcp' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ZenRows MCP:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zenrowsmcp_batch_status', 25 toolInput: { job_id: 'YOUR_JOB_ID' }, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zenrowsmcp" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ZenRows MCP:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={"job_id":"YOUR_JOB_ID"}, 27 tool_name="zenrowsmcp_batch_status", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Extract records** — Extract structured data from a webpage using ZenRows * **Wait batch, browser** — Poll batch\_status until a ZenRows Batch job reaches a terminal state (completed, stopped, or deleted) * **Status batch** — Get status and stats for a ZenRows Batch job, including latest\_run.status and latest\_run.stats * **Results batch** — List result rows for a ZenRows Batch job * **Create batch** — Submit a cloud Batch job that fans out many URLs asynchronously (ZenRows Batch API, beta) * **Cancel batch** — Stop an in-flight ZenRows Batch job run ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Zoho CRM connector > Connect to Zoho CRM. Manage leads, contacts, accounts, deals, tasks, and other sales activities. 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Zoho CRM credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zohocrm' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Zoho CRM:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zohocrm_v8_accounts_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zohocrm" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Zoho CRM:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="zohocrm_v8_accounts_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Create v8 webhook, v8 record, v8 bulk write job** — Create a workflow-triggered webhook that notifies an external URL when records change in a Zoho CRM module * **Update v8 task, v8 note, v8 mass** — Update an existing task in Zoho CRM * **Search v8 task, v8 lead, v8 deal** — Search for tasks in Zoho CRM using Zoho’s criteria query syntax * **Get v8 task, v8 record, v8 note** — Retrieve a single task from Zoho CRM by its record ID * **Delete v8 task, v8 record, v8 note** — Permanently delete a task from Zoho CRM by its record ID * **Send v8** — Send an email from a Zoho CRM record (e.g ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Zoom connector > Connect to Zoom. Schedule meetings, manage recordings, and handle video conferencing workflows 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your Zoom credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zoom' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Zoom:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zoom_chat_channels_list', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zoom" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Zoom:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="zoom_chat_channels_list", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **List webinars, webinar registrants, tracking fields** — List all scheduled webinars for a Zoom user * **Update webinar, webinar registrant status, tracking field** — Update an existing Zoom webinar’s topic, schedule, or agenda * **Add webinar registrant, webinar panelist, meeting registrant** — Register a new attendee for a Zoom webinar * **Get webinar, tracking field, meeting poll** — Retrieve details of a scheduled Zoom webinar, including its settings, agenda, and occurrence information * **Delete webinar, tracking field, group** — Permanently delete a scheduled Zoom webinar * **Create webinar, tracking field, meeting poll** — Schedule a new Zoom webinar for a user ## Common workflows [Section titled “Common workflows”](#common-workflows) ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # ZoomInfo connector > Connect to ZoomInfo to search and enrich B2B contact and company data, access intent signals, discover technographic insights, and manage GTM Studio... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Set up the connector [Section titled “Set up the connector”](#set-up-the-connector) Register your ZoomInfo credentials with Scalekit so it handles the token lifecycle. You do this once per environment. 4. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zoominfo' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize ZoomInfo:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zoominfo_get_company_lookalikes', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zoominfo" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize ZoomInfo:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="zoominfo_get_company_lookalikes", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **Records upsert gtm entity** — Create or update records for a GTM data model entity (account, contact, or user) * **Sync upsert audience rows** — Synchronously create and/or update up to 50 rows in an audience in one call, returning results immediately in the response * **List workflows, gtm entities, segments** — Get a list of ZoomInfo workflows with optional filtering and pagination * **Get workflow execution status, gtm entity fields, entitlements** — Get the status of a workflow execution previously triggered with Execute Workflow * **Execute workflow** — Execute a ZoomInfo workflow that supports on-demand runs * **Settings upsert** — Create or update the customer settings singleton for the authenticated ZoomInfo account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools… --- # DOCUMENT BOUNDARY --- # Zoom Revenue Accelerator connector > Connect to Zoom Revenue Accelerator (formerly Zoom IQ). Access sales conversation intelligence, deal insights, scorecards, CRM data imports, and team... 1. ### Install the SDK [Section titled “Install the SDK”](#install-the-sdk) * Node.js ```bash 1 npm install @scalekit-sdk/node ``` * Python ```bash 1 pip install scalekit ``` Full SDK reference: [Node.js](/agentkit/sdks/node/) | [Python](/agentkit/sdks/python/) 2. ### Set your credentials [Section titled “Set your credentials”](#set-your-credentials) Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**. .env ```sh SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET= ``` 3. ### Authorize and make your first call [Section titled “Authorize and make your first call”](#authorize-and-make-your-first-call) * Node.js quickstart.ts ```typescript 1 import { ScalekitClient } from '@scalekit-sdk/node' 2 import 'dotenv/config' 3 4 const scalekit = new ScalekitClient( 5 process.env.SCALEKIT_ENV_URL, 6 process.env.SCALEKIT_CLIENT_ID, 7 process.env.SCALEKIT_CLIENT_SECRET, 8 ) 9 const actions = scalekit.actions 10 11 const connector = 'zoomrevenueaccelerator' 12 const identifier = 'user_123' 13 14 // Generate an authorization link for the user 15 const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier }) 16 console.log('Authorize Zoom Revenue Accelerator:', link) 17 process.stdout.write('Press Enter after authorizing...') 18 await new Promise(r => process.stdin.once('data', r)) 19 20 // Make your first call 21 const result = await actions.executeTool({ 22 connector, 23 identifier, 24 toolName: 'zoomrevenueaccelerator_get_crm_registration', 25 toolInput: {}, 26 }) 27 console.log(result) ``` * Python quickstart.py ```python 1 import os 2 from scalekit.client import ScalekitClient 3 from dotenv import load_dotenv 4 load_dotenv() 5 6 scalekit_client = ScalekitClient( 7 env_url=os.getenv("SCALEKIT_ENV_URL"), 8 client_id=os.getenv("SCALEKIT_CLIENT_ID"), 9 client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), 10 ) 11 actions = scalekit_client.actions 12 13 connection_name = "zoomrevenueaccelerator" 14 identifier = "user_123" 15 16 # Generate an authorization link for the user 17 link_response = actions.get_authorization_link( 18 connection_name=connection_name, 19 identifier=identifier, 20 ) 21 print("Authorize Zoom Revenue Accelerator:", link_response.link) 22 input("Press Enter after authorizing...") 23 24 # Make your first call 25 result = actions.execute_tool( 26 tool_input={}, 27 tool_name="zoomrevenueaccelerator_get_crm_registration", 28 connection_name=connection_name, 29 identifier=identifier, 30 ) 31 print(result) ``` ## What you can do [Section titled “What you can do”](#what-you-can-do) Connect this agent connector to let your agent: * **To revoke team access, grant team access** — Stop the current team from granting the specified target teams access to its conversation recordings * **From revoke team access, grant team access** — Stop the specified source teams from granting the current team access to their conversation recordings * **Event multipart upload** — Initiate a multipart file upload (to obtain an upload\_context for uploading parts) or complete one after all parts have been uploaded * **Team move** — Move a Revenue Accelerator team under a new parent team, changing the account’s team hierarchy * **Update team, conversation host, conversation comment** — Update the name of a specific Revenue Accelerator team * **Crm unregister, register** — Unregister the current custom CRM API integration for this Zoom account ## Tool list [Section titled “Tool list”](#tool-list) Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you’re not sure which name to use, list the tools available for the current user first. Filter tools…