- Updated: March 21, 2026
- 8 min read
Extending the OpenClaw Go CLI Tool to Publish Ratings on Moltbook
You can extend the OpenClaw Go CLI to publish ratings on Moltbook by adding a Moltbook API client, wiring it into the command flow, handling authentication, and sending a properly formatted HTTP request from your Go code.
1. Introduction
OpenClaw is a lightweight, open‑source Go CLI that helps developers interact with the OpenClaw ecosystem. While the core tool already supports basic CRUD operations, many teams need to push additional data—such as user‑generated ratings—into external services like Moltbook. This guide walks you through a step‑by‑step extension of the OpenClaw CLI so it can publish ratings directly to Moltbook’s REST API.
By the end of this tutorial you will have a fully functional command openclaw moltbook rate that accepts a book ID, a numeric rating, and an optional comment, then posts the data to Moltbook. The article is written for developers comfortable with Go, HTTP, and basic CLI design patterns.
If you plan to host the extended CLI on your own infrastructure, see our OpenClaw hosting guide for deployment best practices.
2. Prerequisites
- Go 1.20+ installed (download)
- Access to a Moltbook API token (request from your Moltbook admin)
- Basic familiarity with Cobra/Viper if you use them for CLI scaffolding
- Git for version control
- Optional: Docker for containerised builds
3. Extending OpenClaw CLI
3.1 Adding Moltbook API client
The first step is to create a small Go package that abstracts Moltbook’s rating endpoint. Keep the client isolated so it can be reused in other projects.
// pkg/moltbook/client.go
package moltbook
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
type RatingRequest struct {
BookID string `json:"book_id"`
Score int `json:"score"` // 1‑5
Comment string `json:"comment,omitempty"`
Reviewer string `json:"reviewer"` // optional identifier
}
type Client struct {
BaseURL string
HTTPClient *http.Client
Token string
}
// NewClient creates a Moltbook client with a timeout.
func NewClient(baseURL, token string) *Client {
return &Client{
BaseURL: baseURL,
Token: token,
HTTPClient: &http.Client{
Timeout: 10 * time.Second,
},
}
}
// PublishRating sends a rating to Moltbook.
func (c *Client) PublishRating(req RatingRequest) error {
endpoint := fmt.Sprintf("%s/api/v1/ratings", c.BaseURL)
payload, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("marshal rating request: %w", err)
}
httpReq, err := http.NewRequest(http.MethodPost, endpoint, bytes.NewBuffer(payload))
if err != nil {
return fmt.Errorf("create request: %w", err)
}
httpReq.Header.Set("Authorization", "Bearer "+c.Token)
httpReq.Header.Set("Content-Type", "application/json")
resp, err := c.HTTPClient.Do(httpReq)
if err != nil {
return fmt.Errorf("perform request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
return fmt.Errorf("unexpected status: %s", resp.Status)
}
return nil
}
The client follows Go’s idiomatic error handling and uses a short timeout to avoid hanging the CLI. You can inject a custom http.Client for testing or for advanced scenarios such as proxy support.
3.2 Wiring the client into OpenClaw
Assuming your OpenClaw project already uses Cobra for command definitions, add a new sub‑command called moltbook rate. The command parses flags, builds a RatingRequest, and calls the client.
// cmd/moltbook_rate.go
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/yourorg/openclaw/pkg/moltbook"
)
var moltbookRateCmd = &cobra.Command{
Use: "rate",
Short: "Publish a rating to Moltbook",
RunE: runMoltbookRate,
}
func init() {
moltbookCmd.AddCommand(moltbookRateCmd)
moltbookRateCmd.Flags().String("book-id", "", "ID of the book to rate (required)")
moltbookRateCmd.Flags().Int("score", 0, "Rating score between 1 and 5 (required)")
moltbookRateCmd.Flags().String("comment", "", "Optional comment")
moltbookRateCmd.Flags().String("reviewer", "", "Optional reviewer identifier")
moltbookRateCmd.MarkFlagRequired("book-id")
moltbookRateCmd.MarkFlagRequired("score")
}
// runMoltbookRate executes the rating publish flow.
func runMoltbookRate(cmd *cobra.Command, args []string) error {
bookID, _ := cmd.Flags().GetString("book-id")
score, _ := cmd.Flags().GetInt("score")
comment, _ := cmd.Flags().GetString("comment")
reviewer, _ := cmd.Flags().GetString("reviewer")
// Load token from environment variable for simplicity.
token := os.Getenv("MOLTBOOK_API_TOKEN")
if token == "" {
return fmt.Errorf("MOLTBOOK_API_TOKEN not set")
}
client := moltbook.NewClient("https://api.moltbook.com", token)
rating := moltbook.RatingRequest{
BookID: bookID,
Score: score,
Comment: comment,
Reviewer: reviewer,
}
if err := client.PublishRating(rating); err != nil {
return fmt.Errorf("failed to publish rating: %w", err)
}
fmt.Println("✅ Rating successfully published to Moltbook")
return nil
}
The command reads the API token from the MOLTBOOK_API_TOKEN environment variable, a common practice for CI/CD pipelines. You can replace this with a config file or a secret manager if you prefer.
4. Publishing Ratings
With the new sub‑command in place, publishing a rating is a single line in the terminal:
MOLTBOOK_API_TOKEN=your_token_here openclaw moltbook rate --book-id=12345 --score=4 --comment="Great read!" --reviewer="dev@example.com"
The CLI will output a confirmation message if the HTTP 201 Created response is received. Internally, the request payload looks like this:
{
"book_id": "12345",
"score": 4,
"comment": "Great read!",
"reviewer": "dev@example.com"
}4.1 API request example (cURL)
For debugging, you can replicate the request with curl:
curl -X POST https://api.moltbook.com/api/v1/ratings \
-H "Authorization: Bearer your_token_here" \
-H "Content-Type: application/json" \
-d '{"book_id":"12345","score":4,"comment":"Great read!","reviewer":"dev@example.com"}'If the request succeeds, Moltbook returns:
{
"id": "r-9876",
"status": "created",
"created_at": "2024-03-21T12:34:56Z"
}5. Testing the Integration
Automated testing ensures that future changes to OpenClaw or Moltbook’s API won’t break the rating flow. Below is a minimal test suite using Go’s net/http/httptest package.
// pkg/moltbook/client_test.go
package moltbook
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
func TestPublishRating_Success(t *testing.T) {
// Mock Moltbook server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Fatalf("expected POST, got %s", r.Method)
}
if r.Header.Get("Authorization") != "Bearer test-token" {
t.Fatalf("missing or wrong auth header")
}
var payload RatingRequest
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
if payload.BookID != "test-book" || payload.Score != 5 {
t.Fatalf("unexpected payload: %+v", payload)
}
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"id":"r-1","status":"created"}`))
}))
defer server.Close()
client := NewClient(server.URL, "test-token")
req := RatingRequest{
BookID: "test-book",
Score: 5,
}
if err := client.PublishRating(req); err != nil {
t.Fatalf("PublishRating failed: %v", err)
}
}
Run the test with go test ./.... The mock server validates the request structure, authentication header, and response handling.
6. Deploying the Updated CLI
After confirming that the new command works locally, you can ship the binary to your users. Below are three common deployment strategies:
- GitHub Releases: Build a multi‑platform binary and attach it to a GitHub release. Users can download the appropriate asset for Windows, macOS, or Linux.
- Docker Image: Publish a lightweight
scratch‑based image that runs the CLI as the entrypoint. This is ideal for CI pipelines that need to rate books automatically. - UBOS Marketplace: If you want a no‑ops solution, upload the binary to the UBOS portfolio and let the platform handle versioning and distribution.
For a quick Docker build, use the following Dockerfile:
# Dockerfile
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o openclaw ./cmd/openclaw
FROM scratch
COPY --from=builder /app/openclaw /openclaw
ENTRYPOINT ["/openclaw"]
Build and push the image:
docker build -t yourrepo/openclaw:latest .
docker push yourrepo/openclaw:latestOnce the image is in a registry, your CI jobs can run:
docker run --rm -e MOLTBOOK_API_TOKEN=$TOKEN yourrepo/openclaw moltbook rate --book-id=9876 --score=57. Additional UBOS Resources for Developers
While extending OpenClaw is a focused task, you might also explore other UBOS services that complement your workflow:
- UBOS platform overview – a unified environment for building, testing, and deploying AI‑enhanced applications.
- Enterprise AI platform by UBOS – scale your AI integrations across teams.
- Workflow automation studio – orchestrate multi‑step processes like rating ingestion, sentiment analysis, and reporting.
- AI marketing agents – automate outreach based on newly published ratings.
- UBOS templates for quick start – jump‑start new projects with pre‑configured Go, Python, or Node templates.
8. Conclusion
Extending the OpenClaw Go CLI to publish ratings on Moltbook is a straightforward process when you follow a modular design: create a dedicated API client, expose a new Cobra command, and validate the integration with unit tests. By packaging the binary for distribution—whether via GitHub releases, Docker, or the UBOS portfolio—you ensure that developers and automation pipelines can reliably push user feedback into Moltbook.
This guide not only solves the immediate rating‑publishing need but also demonstrates a reusable pattern for any future third‑party API integration. Keep your codebase clean, your tests comprehensive, and your deployment pipeline automated, and you’ll be ready to scale your CLI’s capabilities as your product ecosystem grows.
For background on the original OpenClaw announcement, see the official news release.