📘 HubSpot CMS Development Textbook — 2026 Edition
Chapter 9 — CLI · Deploy · MCP

Development environment/CLI/deployment workflow

All HubSpot CLI commands and settings, strategies for managing multiple portals, how to proceed with local development, CI/CD pipelines with GitHub Actions, and best practices for team development. We will organize a system to operate the project safely and quickly.

🎯 Target level:Intermediate to advanced
⏱ Estimated reading completion:60-90 minutes
🔗 Previous chapter:Chapter 8 Performance/SEO/Accessibility
🆕 March 2026 version — CLI v8 / Node 20 / Developer MCP Server compatible

Contents of this chapter

  1. HubSpot CLI setup and authentication v8 compatible
  2. CLI full command reference v8 compatible
  3. Local development flow (watch mode)
  4. Management strategy for multiple portals (separation of development and production)
  5. Synchronization exclusion settings using .hsignore
  6. Advanced settings in hubl.config.yml
  7. Integration with GitHub and GitHub Actions CI/CD v8 compatible
  8. Deployment workflow best practices
  9. HubSpot Developer MCP Server — Accelerate development with AI agents NEW
  10. Best practices for team development
  11. Chapter 9 Summary
Section 9-1

HubSpot CLI setup and authentication

The HubSpot CLI (command line interface) A bidirectional sync tool between your local file system and the HubSpot portal. Rather than operating the design manager on a browser, Fast development with editor and terminalis the biggest advantage.

① Installing Node.js and CLI

⚠️ February 2026 ~ CLI v8.0.0: Node.js 20 required

60 minutesMinimum Node.js version increased to Node 20. Node 18 will end of support for both HubSpot serverless functions and CLI on October 1, 2025. If you are using nvm (Node Version Manager) nvm install 20 && nvm use 20 Please switch. Also in v8 Old command (hs upload/hs watch etc.) are completely deleted.is, hs cms upload/hs cms watch (see Section 9-2).

Terminal — HubSpot CLI installation (Node 20 required)
# Requires Node.js 20 or higher (required for v8.0.0 or later). Check version
$ node --version
v20.x.x ← Must be 20 or more (18.x is NG)

# Globally install HubSpot CLI with npm
$ npm install -g @hubspot/cli

# Confirm installation (v8.0.0 or higher recommended)
$ hs --version
8.x.x

# or run each time with npx (no installation required)
$ npx @hubspot/cli --version

② Authentication settings (first time only)

Terminal — Authenticating to the HubSpot portal
# initialize in project root
$ hs init# Setup proceeds interactively
? Enter a name for this account (e.g. "my-sandbox"): my-company-dev
? Enter your HubSpot portal ID: 12345678
? How would you like to authenticate your account?
  ❯ Personal Access Key (recommended)
    OAuth2

# Select Personal Access Key and your browser will open.
# You can issue a Personal Access Key from the HubSpot admin screen
# Obtained from Developer Accounts → Account → Personal Access Keys

? Enter your personal access key: eu1-xxxx-xxxx-xxxx-xxxx
✔ Authenticated account: my-company-dev (12345678)
✔ Config file created: ~/.config/@hubspot/cli/config.yml

③ Check the configuration file for the project

hs init When you run hubspot.config.yml will be generated. This file is the starting point for CLI configuration.

hubspot.config.yml — Initial generated configuration file
defaultPortal: my-company-dev
portals:
  - name: my-company-dev
    portalId: 12345678
    authType: personalaccesskey
    personalAccessKey: eu1-xxxx-xxxx-xxxx-xxxx
    auth:
      tokenInfo:
        accessToken: CJa...
        expiresAt: '2024-12-31T00:00:00.000Z'
⚠️ hubspot.config.yml must be added to .gitignore

hubspot.config.yml contains your Personal Access Key (access token). Never commit to a Git repository. Immediately after creating the project .gitignore and add it to Each team member has their own hs init I'd like you to do this. In the production CI/CD environment, we will design the token to be passed via environment variables (described later).


Section 9-2 ★ CLI v8 compatible

CLI full command reference

⚠️ CLI v8 (from February 2026): Command system has changed

From October 2025, CMS related commands will be added to hs cms namespace Moved to. CLI v8.0.0 uses the old command (hs uploadhs watch etc.) isComplete deletionIt has been. CI/CD pipeline and package.json If any old commands remain in your scripts, you need to update them immediately. Please check the compatibility between the old and new versions in the table below.

Old command → new command correspondence table

Old command (removed in v8)New command (current official command)Purpose
hs uploadhs cms uploadUpload files/directories to HubSpot
hs watchhs cms watchMonitor changes and automatically upload (constantly used during development)
hs fetchhs cms fetchDownload files locally from HubSpot
hs linths cms lintHubL syntax check
hs lisths cms listFile list display on HubSpot
hs mvhs cms mvMoving/renaming files on HubSpot
hs removehs cms deleteDelete files and folders on HubSpot
hs create themehs cms app / npx create-cms-themeGeneration of theme template
hs create modulehs cms moduleCustom module template generation
hs theme previewhs cms theme previewLaunch theme preview
hs theme marketplace-validatehs cms theme marketplace-validateValidation for marketplaces
hs function ...hs cms function ...General operations for serverless functions
hs logshs cms function logsCheck logs of serverless functions

List of main commands (v8 new system)

hs cms upload <src> <dest>
Upload local files and directories to HubSpot
--portal=name --overwrite
hs cms watch <src> <dest>
Monitor file changes and automatically upload any changes (constantly used during development)
--portal=name --remove
hs cms fetch <src> <dest>
Download files locally from HubSpot (used for initial acquisition and checking differences)
--portal=name --overwrite
hs cms lint <src>
Check HubL syntax errors/warnings. Always run before deploying
--portal=name
hs cms list <path>
Display a list of files under a specified path on HubSpot
--portal=name
hs cms mv <src> <dest>
Move or rename files and folders on HubSpot
--portal=name
hs cms delete <path>
Delete files and folders on HubSpot (old: hs remove)
--portal=name
hs cms module <name>
Generate custom module template (5 files)
--path=destination path
hs cms theme preview
Launch a local preview of a theme
--portal=name
hs cms function logs
Check logs for deployed serverless functions (old: hs logs)
--portal=name --follow
hs project upload
Build and upload Projects framework (React/v2025.2)
--portal=name
hs auth
Monthly performance check and minor corrections (about 1-2 hours/month)

Practical usage of commands (v8 compatible)

Terminal — Frequently used command patterns (v8 new system)
# ===== Upload the entire theme =====
$ hs cms upload ./src/my-theme @my-theme --portal=my-company-dev

# ===== Start watch mode during development =====
$ hs cms watch ./src/my-theme @my-theme --portal=my-company-dev
Watcher started, watching "./src/my-theme"
Uploaded "templates/page.html" to "@my-theme/templates/page.html"
Uploaded "modules/hero-banner.module/module.html"

# ===== Get the latest from HubSpot (before checking the difference) =====
$ hs cms fetch @my-theme ./src/my-theme-remote --portal=my-company-prod --overwrite

# ===== Lint check before deployment =====
$ hs cms lint ./src/my-theme --portal=my-company-dev
✔ No lint errors found

# ===== Upload only specific files =====
$ hs cms upload ./src/my-theme/modules/hero-banner.module @my-theme/modules/hero-banner.module

# ===== Generate new module template =====
$ hs cms module pricing-table --path=./src/my-theme/modules
✔ Created "pricing-table.module" at ./src/my-theme/modules/pricing-table.module

# ===== Check portal file list =====
$ hs cms list --portal=my-company-prod
@my-theme/
├── templates/
├── modules/
├── css/
├── js/
└── theme.json

Utilizing hs cms lint

Terminal — Check and respond to lint errors
$ hs cms lint ./src/my-theme

✖ Error in "templates/blog-post.html" line 42:
  Unexpected tag: endmodule (did you mean end_module?)

⚠ Warning in "modules/card-grid.module/module.html" line 18:
  Variable "module.subtitle" used but not defined in fields.json

Lint complete: 1 error, 1 warning

# Rerun after fixing the error
$ hs cms lint ./src/my-theme
✔ No lint errors found (1 warning)

Section 9-3

Local development flow (watch mode)

Development in practice hs cms watch Use the editor with . Every time you save a file, it's automatically uploaded to HubSpot. You can check it immediately by reloading your browser.

Recommended directory structure

Project root configuration
my-project/
├── src/                         # ← Files to be synchronized using CLI
│   └── my-theme/               # Theme body
│       ├── theme.json
│       ├── templates/
│       ├── modules/
│       ├── css/
│       ├── js/
│       └── images/
├── .gitignore
├── .hsignore                    # define files that CLI ignores
├── hubspot.config.yml           # Authentication settings (add to .gitignore)
├── package.json                  # Define development commands with npm scripts
└── README.md                    # Setup instructions documentation

Organize commands in package.json

package.json — Definition of development commands
{
  "name": "my-company-hubspot",
  "version": "1.0.0",
  "scripts": {

    // ===== Development commands =====
    "dev": "hs cms watch src/my-theme @my-theme --portal=dev",
    // Start watch mode with npm run dev (sync to dev portal)

    // ===== Deploy command =====
    "deploy:dev"  : "hs cms upload src/my-theme @my-theme --portal=dev --overwrite",
    "deploy:prod" : "hs cms upload src/my-theme @my-theme --portal=prod --overwrite",

    // ===== Check command =====
    "lint"       : "hs cms lint src/my-theme --portal=dev",
    "fetch:prod"  : "hs cms fetch @my-theme src/my-theme-remote --portal=prod --overwrite",

    // ===== Compound command =====
    "predeploy:prod": "npm run lint"
    // Automatically run lint before deploy:prod (aborts deployment if there is an error)
  },
  "devDependencies": {
    "@hubspot/cli": "^8.0.0"
    // Specify CLI v8 or higher (Node.js 20 required)
  }
}
Terminal — Everyday commands for development
# === At the start of daily development ===
$ npm run devWatcher started, watching "src/my-theme"
# Edit the file in the editor → Save → Automatically upload → Confirm reload in the browser

# === Stop watch with Ctrl+C when finished ===

# === Checks before production deployment ===
$ npm run lint✔ No lint errors found

# === Production deployment (executed only if lint passes) ===
$ npm run deploy:prodUploading "src/my-theme" to "@my-theme" on portal "prod"...
✔ Done uploading 48 files

Section 9-4

Management strategy for multiple portals (separation of development and production)

In the actual caseDevelopment portal (Sandbox/Developer Account)and User privilege managementseparate and manage. Watching the production environment directly is strictly prohibited as it may cause accidents.

Overview of portal configuration

💻
local
src/ directory
🧪
Development portal
Developer Account / Sandbox
🚀
User privilege management
Client production environment

hubspot.config.yml configuration for multiple portals

hubspot.config.yml — Multiple portal configuration
# Default portal (used when --portal is omitted in hs cms upload)
defaultPortal: dev

portals:
  # ===== Development portal (for daily development) =====
  - name: dev
    portalId: 11111111
    authType: personalaccesskey
    personalAccessKey: eu1-dev-key-xxxxxxxxxx

  # ===== Production portal (only when deploying) =====
  - name: prod
    portalId: 22222222
    authType: personalaccesskey
    personalAccessKey: eu1-prod-key-xxxxxxxxxx

  # ===== For client verification (optional) =====
  - name: staging
    portalId: 33333333
    authType: personalaccesskey
    personalAccessKey: eu1-staging-key-xxxxxxxxxx

Operation rules by portal

portalUsage sceneUsing watchEdit management screen
Development portal (dev) Daily development and operation confirmation ✅ Recommended freely possible
staging As a general rule, approval should be obtained in writing (email/Slack) rather than orally. Just saying "No problem" is OK. ⚠️ Be careful limitedly
Production portal (prod) Final deployment only 🚫 Forbidden Prohibited in principle
⚠️ Watching the actual performance is strictly prohibited.

hs cms watch When I launch it towards the production portal, Unfinished code under development is immediately reflected in production. Be sure to upload to production hs cms upload Run it manually with the command, Please consciously check the contents of your deployment before proceeding.
package.json dev Make it a habit to regularly check that your scripts are always pointing to the development portal.


Section 9-5

Synchronization exclusion settings using .hsignore

.hsignore The file is .gitignore In the same format as hs cms upload or hs cms watch Specify the files and directories that you do not want to synchronize.

# ===== .hsignore ===== 1-1 CLI v8.0.0 overview and breaking changes # system file .DS_Store Thumbs.db desktop.ini # Editor settings .vscode/ .idea/ *.swp *~ # Development files (no need to upload) *.md *.txt package.json package-lock.json node_modules/ # Local development files (tests, mocks, etc.) __tests__/ *.test.js *.spec.js mock-data/ # Build output (when using SCSS etc.) .sass-cache/ *.map # backup file *.bak *.orig
Move under project secret

*.md of .hsignore Command namespace migrated package.json or node_modules/ etc.


Section 9-6

Advanced settings in hubl.config.yml

hubspot.config.yml In addition to authentication information, There are options to further customize CLI behavior.

hubspot.config.yml — Advanced configuration options
defaultPortal: dev

# ===== CLI global settings =====
httpTimeout: 30000
# API request timeout (ms)
# Increase this value when uploading large themes

allowUsageTracking: false
Move under cms subcommand

portals:
  - name: dev
    portalId: 11111111
    authType: personalaccesskey
    personalAccessKey: eu1-dev-key

    # ===== Portal individual settings =====
    defaultMode: write
    # write (upload priority) / read (download priority)

  - name: prod
    portalId: 22222222
    authType: personalaccesskey
    personalAccessKey: eu1-prod-key
    defaultMode: write

Section 9-7

Integration with GitHub and GitHub Actions CI/CD

By linking Git repositories and GitHub Actions, "Automatically deploy to production once merged into main branch" You can build a CI/CD pipeline called

branch strategy

📋 Recommended branching strategy
🌿
feature/xxx
Cut by function
local development
→ PR →
🔀
develop
Go to development portal
suitable case
→ PR →
staging
to staging
suitable case
→ PR →
🚀
main
Make things that can be controlled in fields a field.
suitable case

Configuring GitHub Secrets

Register your Personal Access Key to Secrets in your GitHub repository. Configure from the GitHub repository page → Settings → Secrets and variables → Actions.

Secret namevalue
HUBSPOT_PORTAL_ID_DEVPortal ID of the development portal
HUBSPOT_ACCESS_KEY_DEVDevelopment Portal Personal Access Key
HUBSPOT_PORTAL_ID_PRODPortal ID of the production portal
HUBSPOT_ACCESS_KEY_PRODPersonal Access Key for the production portal

Implementing GitHub Actions workflows

.github/workflows/deploy-dev.yml — Deploy to develop branch
name: Deploy to Dev Portalon:
  push:
    branches:
      - develop

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install HubSpot CLI
        run: npm install -g @hubspot/cli

      - name: Create HubSpot config
        # Dynamically generate hubspot.config.yml from Secrets
        run: |
          cat > hubspot.config.yml << EOF
          defaultPortal: dev
          portals:
            - name: dev
              portalId: ${{ secrets.HUBSPOT_PORTAL_ID_DEV }}
              authType: personalaccesskey
              personalAccessKey: ${{ secrets.HUBSPOT_ACCESS_KEY_DEV }}
          EOF

      - name: Lint check
        run: hs cms lint src/my-theme --portal=dev

      - name: Deploy to Dev
        run: hs cms upload src/my-theme @my-theme --portal=dev --overwrite

      - name: Notify Slack on success
        if: success()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "✅ 開発環境へのデプロイ完了: ${{ github.event.head_commit.message }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
.github/workflows/deploy-prod.yml — Production deployment to main branch
name: Deploy to Productionon:
  push:
    branches:
      - main

jobs:
  lint:
    name: Lint Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm install -g @hubspot/cli
      - name: Create config
        run: |
          cat > hubspot.config.yml << EOF
          defaultPortal: dev
          portals:
            - name: dev
              portalId: ${{ secrets.HUBSPOT_PORTAL_ID_DEV }}
              authType: personalaccesskey
              personalAccessKey: ${{ secrets.HUBSPOT_ACCESS_KEY_DEV }}
          EOF
      - run: hs cms lint src/my-theme --portal=dev

  deploy:
    name: Deploy to Production
    needs: lint        # Execute only if lint job is successful
    runs-on: ubuntu-latest
    environment: production   New creation of the old API key (hapikey parameter) will be discontinued after November 2022.
      Whenever you update an existing integration,

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm install -g @hubspot/cli

      - name: Create production config
        run: |
          cat > hubspot.config.yml << EOF
          defaultPortal: prod
          portals:
            - name: prod
              portalId: ${{ secrets.HUBSPOT_PORTAL_ID_PROD }}
              authType: personalaccesskey
              personalAccessKey: ${{ secrets.HUBSPOT_ACCESS_KEY_PROD }}
          EOF

      - name: Deploy to Production
        run: hs cms upload src/my-theme @my-theme --portal=prod --overwrite

      - name: Notify on success
        if: success()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "🚀 本番デプロイ完了!\ncommit: ${{ github.event.head_commit.message }}\nby: ${{ github.actor }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

      - name: Notify on failure
        if: failure()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "❌ 本番デプロイ失敗!確認が必要です。\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
✅ Put approval gates on production deployments with GitHub Environments

On GitHub, go to Settings → Environments production Create an environment, Setting Required reviewers Approval from specified members is required after merging to main and before deployingIt will be. Workflow environment: production is linked to this. It is very effective as a safety device to prevent unintended production deployment.


Section 9-8 ★ New (February 2026 GA)

HubSpot Developer MCP Server — Accelerate development with AI agents

February 19, 2026HubSpot Developer MCP Server is officially GA (publicly available)It was done. MCP (Model Context Protocol) is a standard for AI tools to collaborate with external services. By installing HubSpot's Developer MCP Server locally, AI editors such as VS Code, Claude Code, and Cursor Generate, deploy, and debug CMS assets using natural language while referring to HubSpot's developer documentation.It will look like this.

🛠️ Developer MCP Server (local)

A server that installs through the CLI and runs locally. Connect to HubSpot's developer platform to scaffold projects, manage CMS assets, and debug serverless functions in natural language.Requires CLI v8.0.0 or higher and Platform v2025.2.

🌐 HubSpot MCP Server (Remote)

A remote server connecting to mcp.hubspot.com. Provide real-time access to HubSpot CRM data to answer queries like "Get this contact's latest activity." Uses OAuth 2.0 authentication.

Setup steps

Terminal — Installing Developer MCP Server
# Prerequisite: CLI v8.0.0 or higher has been installed
$ hs --version
8.x.x

# Set up MCP Server (interactive)
$ hs mcp setup# ↓ Select MCP client to connect interactively
? Which clients would you like to add the MCP server to?
  ❯ ◉ VS Code
    ◉ Claude Code
    ◯ Cursor
    ◯ OpenAI Codex
(Use arrow keys and spacebar to select, Enter to proceed)

✔ HubSpotDev MCP server has been added to: VS Code, Claude Code
Restart your client to apply the changes.

What you can do with MCP server

taskExample prompt to AI
module generation "Create a React module called pricing-table. It has a grid layout that displays 3 columns of pricing plans, and a field design that can display the title, price, and feature list in each column."
template generation "Create a new page template called Product Landing. It consists of 3 blocks: hero section, feature grid, and CTA section, and all of them are compatible with dnd_area."
error debug "An 'Unable to initialize extension' error occurs during local development in NewCard.tsx. Please check the file and suggest a fix."
Check how to use CLI How to migrate:
Deployment "Once you have confirmed your changes, please upload them to the dev portal"
serverless functions "Create a serverless function with a POST /api/submit-form endpoint and include the logic to register the form data with HubSpot CRM."
✅ Best practices for utilizing MCP servers

The most effective usage is "initial scaffolding of module templates". Field design template generation, serverless function boilerplate generation, etc. Delegating repetitive tasks to AI greatly speeds up development.

In addition, the HubSpot documentation says "The most stable results are obtained using Claude Sonnet 4 or higher." It is stated. The combination of MCP server and Claude Code is currently the recommended configuration.

Points to note:MCP Server requires Developer Platform v2025.2. old project is hs project migrate # Help list


Section 9-9

Deployment workflow best practices

Pre-deployment checklist

🚀 Confirmation flow before production deployment
🔍
hs cms lint
No syntax errors
🌐
cross browser
Chrome/Safari/Edge
📱
responsive
SP/Tab/PC
Lighthouse
90 points or more
🚀
deploy:prod
Production deployment

Rollback procedure

HubSpot design managerVersion history featureThere is, You can revert to previous versions from the change history of each file. However, bulk upload via CLI overwrites all files, so Version control using “Git tag + hs cms upload” is a safe rollback methodIt will be.

Terminal — Version control and rollback using tags
# === Always use Git tag during production deployment ===
$ git tag v1.2.0 -m "Hero Banner Renewal"
$ git push origin v1.2.0

# === Rollback if problems are discovered after deployment ===

# ① Check out the tag of the version you want to rollback
$ git checkout v1.1.0
HEAD is now at abc1234 v1.1.0

# ② Upload old version file to production
$ hs upload src/my-theme @my-theme --portal=prod --overwrite
✔ Rollback complete: v1.1.0 deployed to production

# ③ Return to working branch
$ git checkout main

# ④ Correct the problematic changes and redeploy

Deployment strategy for large-scale changes


Section 9-10

Best practices for team development

Documentation of directory structure

README.md — Setup guide for team members
# my-company-hubspot

## Prerequisites
- Node.js 20 or higher (CLI v8.0.0 or later required)
- @hubspot/cli global installation
- Access rights to the development portal (portal ID is shared separately)

## Setup steps

### 1. Clone the repository
git clone https://github.com/mycompany/hubspot-theme.git
cd hubspot-theme

### 2. HubSpot CLI authentication settings
hs init
# Development portal ID: 12345678 (separately shared on Slack)
# Personal Access Key: Issued individually from the HubSpot admin screen
# https://app.hubspot.com/personal-access-key/12345678

◎ Can be set in detail
# ✅ CMS - Design Manager
# ✅ Content

### 4. Start development
npm run dev
# Open the development portal in your browser and check your edits
# https://app.hubspot.com/website-pages/12345678

## Branch strategy
# feature/xxx → develop (automatically deploy to DEV portal)
# develop → main (automatically deploy to production portal)

Required scope for Personal Access Key

scopeWhat you need to do
CMS - Design ManagerUpload/download templates/modules/themes (required)
ContentViewing/editing pages/blog articles (required for template confirmation)
HubDBHubDB table operations (when using HubDB)
FormsForm confirmation/test (required for form development)

Common conflict problems and solutions

⚙️ "Someone edited it directly on the admin screen" issue

When multiple developers and marketers are working at the same time, Editing directly from the admin screen and uploading from the CLI may conflict.

What to do:
① Always deploy from CLI --overwrite Run with flag.
② Create operational rules that prohibit direct editing on the management screen and require changes to be made through local code.
③ If important changes have been made on the management screen,hs cms fetch , import it locally, update the code, and then upload it.
④ Say "I'm going to deploy now" in chat (Slack, etc.) to prevent simultaneous deployments.

Code review points

Personal Access Key expiration management

Personal Access Keys do not have an expiration date, but For security reasons, we recommend regular rotation every 6 months to 1 year. If a team member leaves the company, please deactivate it immediately. Don't forget to update your GitHub Secrets.

📌 Points to keep in mind in this chapter (2026 edition)

CLI v8: Node 20 required/command system changed

CLI v8.0.0 is effective from February 9, 2026. Node.js 20 or higher is required.hs uploadOld commands such as etc. have been completely deleted. all hs cms upload / hs cms watch Shift to a new system such as

Leverage AI development with Developer MCP Server

February 2026 GA's HubSpot Developer MCP Server allows you to generate, deploy, and debug modules using natural language from VS Code and Claude Code. Requires CLI v8 + Platform v2025.2.

Separate environments to prevent production accidents

Basically, the two portals for development and production are separated.hs cms watch is for development portal only. Uploading to production hs cms upload Execute it explicitly with GitHub Actions and automate it with GitHub Actions.

Never commit hubspot.config.yml

Be sure to include your Personal Access Key. .gitignore Added to. In CI/CD, pass the token via environment variable and dynamically generate yml.

Automate CI/CD with GitHub Actions

develop push → Automatically deploy to the development portal, main push → Automatically deploy to the production portal. before deployment hs cms lint Be sure to pass. GitHub Deploy Action uses v1.7 or higher.

Prevent conflicts with team rules

Direct editing on the management screen is prohibited, and changes must be made through local code. Before deployment, let's talk on Slack etc. If a conflict occurs hs cms fetch Get the remote with and then resolve.

Next chapter: Chapter 10 Maintenance, operation, and handover design

We will explain the design of the maintenance system after delivery, handover documents to clients, response to HubSpot updates, and long-term operation checklist.

Go to Chapter 10 →