Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
GOCLAW_GATEWAY_TOKEN=
GOCLAW_ENCRYPTION_KEY=
POSTGRES_PASSWORD=
MCP_RUNTIME_ACCESS_TOKEN=

# --- Database (only for non-Docker deployments) ---
# Docker Compose auto-builds this from POSTGRES_USER/PASSWORD/DB.
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
> [!NOTE]
> This repository is a customized fork of GoClaw maintained by **trwng-thdat**, serving as the execution runtime container for the **AI Claw** SaaS platform ([ai-claw](file:///C:/HCMUS/Jarvis/ai-claw)).

<p align="center">
<img src="_statics/goclaw-logo.svg" alt="GoClaw" height="200" />
</p>

<p align="center"><strong>Multi-Tenant AI Agent Platform</strong></p>
<p align="center"><strong>Multi-Tenant AI Agent Platform (Custom Fork)</strong></p>

<p align="center">
Multi-agent AI gateway built in Go. 20+ LLM providers. 7 channels. Multi-tenant PostgreSQL.<br/>
Expand Down Expand Up @@ -149,13 +152,13 @@ git tag lite-v0.1.0 && git push origin lite-v0.1.0
### From Source

```bash
git clone -b main https://github.com/nextlevelbuilder/goclaw.git && cd goclaw
git clone -b dev https://github.com/trwng-thdat/goclaw.git && cd goclaw
make build
./goclaw onboard # Interactive setup wizard
source .env.local && ./goclaw
```

> **Note:** The default branch is `dev` (active development). Use `-b main` to clone the stable release branch.
> **Note:** The default branch is `dev` (active development). We use the `dev` branch to build and align with the `ai-claw` parent repository.

### With Docker

Expand Down
12 changes: 10 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ services:
dockerfile: Dockerfile
args:
ENABLE_OTEL: "${ENABLE_OTEL:-false}"
ENABLE_EMBEDUI: "${ENABLE_EMBEDUI:-true}" # set to false when using WITH_WEB_NGINX
ENABLE_EMBEDUI: "${ENABLE_EMBEDUI:-true}" # set to false when using WITH_WEB_NGINX
ENABLE_PYTHON: "${ENABLE_PYTHON:-true}"
ENABLE_FULL_SKILLS: "${ENABLE_FULL_SKILLS:-false}"
VERSION: "${GOCLAW_VERSION:-dev}"
Expand All @@ -47,6 +47,7 @@ services:
- GOCLAW_GATEWAY_TOKEN=${GOCLAW_GATEWAY_TOKEN:?run ./prepare-env.sh or set GOCLAW_GATEWAY_TOKEN}
- GOCLAW_ENCRYPTION_KEY=${GOCLAW_ENCRYPTION_KEY:-}
- GOCLAW_SKILLS_DIR=/app/data/skills
- GOCLAW_POSTGRES_DSN=postgres://postgres:postgres@postgres:5432/goclaw?sslmode=disable
# Debug
- GOCLAW_TRACE_VERBOSE=${GOCLAW_TRACE_VERBOSE:-0}
- BITRIX24_LOG_RAW_EVENT=${BITRIX24_LOG_RAW_EVENT:-0}
Expand Down Expand Up @@ -78,7 +79,14 @@ services:
- default
- goclaw-net
restart: unless-stopped

postgres:
image: pgvector/pgvector:pg16
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: goclaw
ports:
- "5434:5432"
volumes:
goclaw-data:
goclaw-workspace:
Expand Down
Binary file added goclaw.exe
Binary file not shown.
38 changes: 38 additions & 0 deletions internal/mcp/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package mcp

import (
"net/http"
"os"

"github.com/google/uuid"
"github.com/nextlevelbuilder/goclaw/internal/store"
)

// ContextAwareRoundTripper reads MCP_RUNTIME_ACCESS_TOKEN and attaches it to the header.
type ContextAwareRoundTripper struct {
Proxied http.RoundTripper
}

func (c *ContextAwareRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
token := os.Getenv("MCP_RUNTIME_ACCESS_TOKEN")
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}

agentID := store.AgentIDFromContext(req.Context())
userID := store.UserIDFromContext(req.Context())

if agentID != uuid.Nil {
req.Header.Set("X-GoClaw-Agent-Id", agentID.String())
}
if userID != "" {
req.Header.Set("X-GoClaw-User-Id", userID)
}

transport := c.Proxied
if transport == nil {
transport = http.DefaultTransport
}
return transport.RoundTrip(req)
}

12 changes: 12 additions & 0 deletions internal/mcp/manager_connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -284,20 +285,31 @@ func (m *Manager) registerPoolBridgeTools(entry *poolEntry, serverName, toolPref

// createClient creates the appropriate MCP client based on transport type.
func createClient(transportType, command string, args []string, env map[string]string, url string, headers map[string]string) (*mcpclient.Client, error) {

authHTTPClient := &http.Client{
Transport: &ContextAwareRoundTripper{
Proxied: http.DefaultTransport,
},
}

switch transportType {
case "stdio":
envSlice := mapToEnvSlice(env)
return mcpclient.NewStdioMCPClient(command, envSlice, args...)

case "sse":
var opts []transport.ClientOption
opts = append(opts, transport.WithHTTPClient(authHTTPClient))

if len(headers) > 0 {
opts = append(opts, mcpclient.WithHeaders(headers))
}
return mcpclient.NewSSEMCPClient(url, opts...)

case "streamable-http":
var opts []transport.StreamableHTTPCOption
opts = append(opts, transport.WithHTTPBasicClient(authHTTPClient))

if len(headers) > 0 {
opts = append(opts, transport.WithHTTPHeaders(headers))
}
Expand Down