TopicForge

How to run your first TopicForge batch job locally

Learn how to set up MongoDB, configure the content-api and ai-service, and run your first programmatic SEO batch job on your local machine.

Generated with TopicForge

You can run the TopicForge services on your local machine using Docker or Node.js to test your configuration. This local setup lets you verify your voice profiles and API payloads before you run large production batches. You do not need to deploy code to a cloud environment just to see how your content rules affect the output.

This guide walks you through setting up your local database, configuring the required services, and executing your first local batch run.

Prerequisites for local TopicForge development

To run TopicForge locally, you need two core external components—a database to store job states and an AI provider to generate the text.

First, you need a local MongoDB instance. The content-api service relies on MongoDB to store job configurations, step statuses, and the final generated markdown. You can run MongoDB as a local service on your machine or launch it inside a Docker container. To verify your database is accessible, you can use a tool like MongoDB Compass or run mongosh in your terminal.

Second, you need access to Gemini via Google Cloud Vertex AI. The local generation pipeline relies on Vertex AI to run its prompts. You must have a Google Cloud project with the Vertex AI API enabled. You also need a service account key file downloaded to your local machine. This key file must have the Vertex AI User role assigned to it.

Configuring your local environment settings

The TopicForge architecture splits work between two main services—the content-api (which manages jobs and database state) and the ai-service (which handles the AI generation pipeline). Both services require environment variables to locate the database and authenticate with Vertex AI.

Create a .env file in the root directory of each service. Do not commit these files to your Git repository. Use your .gitignore file to exclude them to protect your credentials.

For the content-api, set the MongoDB connection string and the port:

PORT=3000
MONGO_URI=mongodb://localhost:27017/topicforge
AI_SERVICE_URL=http://localhost:3001

For the ai-service, set the port, the path to your Google Cloud credentials file, and your project details:

PORT=3001
GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/service-account-key.json
GCP_PROJECT_ID=your-gcp-project-id
GCP_REGION=us-central1

The content-api uses the AI_SERVICE_URL variable to route generation requests to the local ai-service container or process.

Launching the content-api and ai-service

You can start both services using Docker Compose or by running them directly with Node.js.

If you prefer Docker, you can define a docker-compose.yml file that spins up MongoDB, the content-api, and the ai-service together. Run the following command in your terminal to start the stack:

docker-compose up

If you prefer running the services natively with Node.js, open two terminal windows.

In the first terminal, navigate to the content-api directory, install the dependencies, and start the development server:

cd content-api
npm install
npm run dev

In the second terminal, navigate to the ai-service directory, install the dependencies, and start the service:

cd ai-service
npm install
npm run dev

Once both services are running, the content-api will listen on port 3000—and the ai-service will listen on port 3001. The services are now ready to communicate during a generation run.

Structuring your batch job payload

To start a run, you send a JSON payload to the POST /v1/jobs endpoint on your local content-api. This payload contains your target topics and the editorial rules that guide the AI.

Here is a realistic example of a payload for a local batch run. In this example, we will generate articles for a hypothetical B2B logistics platform.

{
  "topics": [
    "How to optimize route planning for cold chain logistics",
    "Reducing last-mile delivery failures in urban areas"
  ],
  "voiceProfile": "Write in a pragmatic, direct tone. Avoid hype. Use short sentences and active voice.",
  "productFacts": [
    "Our software reduces delivery delays by 15 percent (example statistic).",
    "The platform integrates with major telematics hardware."
  ],
  "bannedPhrases": [
    "game-changer",
    "revolutionize",
    "in today's digital landscape"
  ]
}

This payload defines the guardrails for the entire batch. The pipeline uses these rules to ensure the generated text matches your brand voice.

Executing the batch job locally

With your services running, you can trigger the job using cURL or an API client like Postman.

Run the following cURL command in your terminal to send the payload to your local server:

curl -X POST http://localhost:3000/v1/jobs \
  -H "Content-Type: application/json" \
  -d @payload.json

Once you send the request, the content-api creates a new job record in MongoDB and returns a JSON response containing the job ID.

{
  "jobId": "job_67890abcde",
  "status": "pending",
  "topicCount": 2
}

Watch your terminal logs for the ai-service. You will see the service process each article through a four-stage AI pipeline. First, it generates the outline. Second, it writes the draft. Third, it runs a voice pass to apply your editorial guardrails and remove banned phrases. Finally, it generates the CTA and SEO metadata. This multi-stage process ensures the output is structured and matches your brand guidelines.

The console logs will display the progress of each stage:

[ai-service] [Job job_67890abcde] Starting outline pass for topic: "How to optimize route planning..."
[ai-service] [Job job_67890abcde] Starting draft pass...
[ai-service] [Job job_67890abcde] Starting voice pass (applying brand guardrails)...
[ai-service] [Job job_67890abcde] Generating CTA and SEO metadata...
[content-api] Job job_67890abcde completed successfully.

Verifying the generated markdown and metadata

Once the terminal logs show that the job is complete, you can verify the output. Since you are running locally, the completed articles are stored in your local MongoDB database.

Open MongoDB Compass and connect to your local database instance. Navigate to the articles collection inside the topicforge database. Each document in this collection represents one generated article from your batch.

Verify that each document contains the following fields:

  • markdownBody—the full text of the article formatted in clean Markdown.
  • metaDescription—a concise, SEO-friendly summary of the article.
  • faqJsonLd—structured schema markup containing the generated FAQs.
  • cta—a tailored call to action based on your brand guidelines.

Reviewing these database entries locally helps you verify that your voice profiles and brand guardrails work as intended before you scale up your production runs.


Setting up TopicForge locally gives you full control over your programmatic SEO workflow before moving to production. When you are ready to scale your content production without managing local infrastructure, TopicForge offers a pay-per-article model—starting at $10 for a single article, $49 for a 10-pack, or $399 for a 100-pack. You can run batch jobs through the cloud API to generate dozens of publish-ready articles in a single call.

FAQs

Can I run TopicForge locally without a MongoDB database?

No, the content-api relies on MongoDB to store job states, configuration settings, and the final generated articles. You must run a local MongoDB instance—either natively or via a Docker container—to execute batch jobs.

Which AI models power the local generation pipeline?

The local ai-service connects to Gemini via Vertex AI. You will need to configure your Google Cloud credentials locally so the service can authenticate and run the multi-stage generation pipeline.

How do I apply custom voice profiles to a local batch run?

You define your voice profile, product facts, and banned phrases within the JSON payload sent to the POST /v1/jobs endpoint. The local ai-service applies these guardrails to every article generated during the batch run.

← More from Using TopicForge