SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor

SandBase agent runtime को self-host कैसे करें

SandBase Harness v0.3.2 को अपने VPS पर सेटअप करें। इस गाइड में tagged install, agent YAML कॉन्फ़िगरेशन, MCP servers और Anthropic SDK को अपने सर्वर से जोड़ने की प्रक्रिया दी गई है।

SandBase agent runtime को self-host करने पर आपको क्या मिलता है

SandBase agent runtime को self-host करने का अर्थ है SandBase Harness को अपने स्वयं के सर्वर पर चलाना। इससे sessions, credentials, memory और audit trails किसी और के सर्वर के बजाय आपकी अपनी डिस्क पर सुरक्षित रहते हैं। यह एक Node service है। यह 127.0.0.1:3000 पर listen करती है, एक /v1 HTTP API और web console प्रदान करती है, और अपनी state को आपके agent files के साथ SQLite में रखती है।

/v1 API को Claude Managed Agents (CMA) के आधार पर तैयार किया गया है, जो कि एक hosted managed-agent API है। यही बात इस runtime को दोनों दिशाओं में उपयोगी बनाती है: आप Anthropic SDK का उपयोग करके कोड लिख सकते हैं और इसके baseURL को अपने सर्वर की ओर निर्देशित कर सकते हैं, और बाद में उसी कोड को किसी hosted deployment पर ले जा सकते हैं।

SandBase Harness के साथ कोई model नहीं आता है। यह एक model को call करता है। अगस्त 2026 तक, यह OpenAI, Anthropic और OpenAI-compatible endpoints को support करता है, जिसमें self-hosted gateways और DeepSeek V4 जैसे providers शामिल हैं। आपको अपना API key स्वयं प्रदान करना होगा, या एक ऐसा local server उपयोग करना होगा जो OpenAI API के अनुरूप हो।

शुरू करने से पहले आपकी आवश्यकताएं

  • कम से कम 2 GB RAM वाला Ubuntu 24.04 पर चलने वाला एक VPS। TypeScript build इंस्टॉलेशन का सबसे भारी चरण है।
  • Node.js 22 या उससे नया, और npm 10 या उससे नया। ये दोनों प्रोजेक्ट द्वारा निर्धारित अनिवार्य न्यूनतम आवश्यकताएं हैं।
  • git, साथ ही जिस मॉडल प्रदाता का आप उपयोग करने की योजना बना रहे हैं, उसके लिए एक API key।
  • Docker, लेकिन केवल तभी यदि आप प्रति-सत्र (per-session) कंटेनर सैंडबॉक्स चाहते हैं।

Ubuntu 24.04 अपने रिपॉजिटरी में Node 18.19 प्रदान करता है, जो न्यूनतम आवश्यकता से कम है, इसलिए Node को NodeSource से प्राप्त करें।

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs git
node -v
npm -v

node -v को v22 या उससे अधिक प्रिंट करना चाहिए और npm -v को 10 या उससे अधिक प्रिंट करना चाहिए। यदि node -v अभी भी v18.19.1 प्रिंट करता है, तो डिस्ट्रीब्यूशन पैकेज अभी भी इंस्टॉल है और PATH पर प्राथमिकता ले रहा है। आगे बढ़ने से पहले इसे हटा दें, क्योंकि build उसी node के विरुद्ध चलती है जिसे shell ढूंढ पाता है।

v0.3.2 tag से SandBase इंस्टॉल करें

किसी moving branch के बजाय हमेशा एक tag से इंस्टॉल करें। main का bare clone आपको वह सब देता है जो एक घंटे पहले ही commit हुआ है, और नीचे दिए गए config keys शायद उससे मेल न खाएं। 16 August 2026 तक v0.3.2 वर्तमान tag है।

sudo install -d -o "$USER" -g "$USER" /opt/sandbase
cd /opt/sandbase
git clone --branch v0.3.2 --depth 1 https://github.com/sandbaseai/sandbase-harness.git
cd sandbase-harness
npm ci
npm run build

npm install के बजाय npm ci का उपयोग करें। ci कमिट किए गए lockfile में दर्ज सटीक versions को इंस्टॉल करता है, ताकि आपका tree उस tree से मेल खाए जिसे maintainers ने टेस्ट किया है। npm install नए versions को resolve करने की अनुमति देता है, और इसी तरह एक pinned tag चुपचाप unpinned हो जाता है।

अब एक workspace बनाएं। workspace एक अलग directory है जो आपकी agent files और सभी runtime state को रखती है, और इसे source checkout के बाहर रखने का मतलब है कि आप अपने data को छुए बिना एक नया tag pull कर सकते हैं।

mkdir -p /opt/sandbase/workspace
cd /opt/sandbase/workspace
node /opt/sandbase/sandbase-harness/dist/index.js init
node /opt/sandbase/sandbase-harness/dist/index.js start

init workspace में एक .managed-agents/ directory लिखता है। start console को http://127.0.0.1:3000/dashboard पर और API को http://127.0.0.1:3000/v1 पर लाता है। अभी इनमें से कोई भी आपके laptop से reachable नहीं है, जो कि सही है और आगे विस्तार से बताया गया है। अभी के लिए SSH के माध्यम से console तक पहुँचें:

ssh -N -L 3000:127.0.0.1:3000 you@your-server

वह लंबा node .../dist/index.js path थकाऊ हो जाता है, इसलिए इसे एक नाम दें।

alias sandbase='node /opt/sandbase/sandbase-harness/dist/index.js'

नीचे दिए गए commands को उसी आधार पर sandbase <command> के रूप में लिखा गया है।

इसे npm से install न करें

Project के अपने installation documentation में यह स्पष्ट लिखा है: npm पर दिखने वाला unscoped managed-agents package इस project का नहीं है। इसलिए npx managed-agents और npm install -g managed-agents चलाने पर आपको वह runtime नहीं मिलेगा जिसकी आपको आवश्यकता है। जब तक maintainers किसी आधिकारिक scoped package की घोषणा नहीं करते, तब तक इसे tagged GitHub source से ही install करें। यह project के इतिहास में कोई छोटी-मोटी बात नहीं है: v0.3.1 का मुख्य उद्देश्य पुराने npm quick start को हटाकर उसे pinned tagged-source path से बदलना है।

वर्कस्पेस को एक मॉडल प्रदाता (model provider) पर पॉइंट करें

init, .managed-agents/config.yaml लिखता है। पूरे वर्कस्पेस के लिए एक प्रदाता कॉन्फ़िगर किया जाता है, और फिर व्यक्तिगत एजेंट्स ठोस मॉडल IDs चुनते हैं।

model:
  provider: openai
  api_key: ${OPENAI_API_KEY}
storage:
  metadata:
    provider: sqlite
    options: {}
  artifacts:
    provider: local
    options:
      base_path: files

${OPENAI_API_KEY} फॉर्म प्रोसेस एनवायरनमेंट से वैल्यू लेता है, इसलिए की (key) कॉन्फ़िगरेशन फ़ाइल से बाहर रहती है और उस फ़ाइल के आपके द्वारा लिए गए किसी भी बैकअप में नहीं जाती है। इसे एक ऐसी एनवायरनमेंट फ़ाइल में रखें जिसे केवल root ही पढ़ सके, क्योंकि systemd विशेषाधिकार (privileges) छोड़ने से पहले EnvironmentFile= को root के रूप में पढ़ता है।

sudo install -d -m 750 /etc/sandbase
sudo touch /etc/sandbase/runtime.env
sudo chmod 600 /etc/sandbase/runtime.env

उस फ़ाइल को किसी एडिटर में खोलें और एक लाइन, OPENAI_API_KEY=sk-... जोड़ें। प्रदाता कीज़ (provider keys) यहीं होनी चाहिए। वे सीक्रेट्स जिनका उपयोग कोई एजेंट सत्र के दौरान करता है, उन्हें रनटाइम के क्रेडेंशियल वॉल्ट में होना चाहिए, जो एक अलग समस्या है और जिसका प्रभाव क्षेत्र (blast radius) अलग है, और AI एजेंट्स से सीक्रेट्स को दूर रखना पढ़ना उचित है, इससे पहले कि आप किसी प्रोडक्शन टोकन को कहीं भी पेस्ट करें।

Agent YAML: mcp_servers, tools और permission policies

Agents को workspace के agents/ directory में YAML files के रूप में define किया जाता है। runtime का यही वह हिस्सा है जहाँ आप वास्तव में अपना समय बिताएंगे।

name: Incident commander
description: Triages alerts and coordinates response.
model: gpt-4o
system: |-
  You are an on-call incident commander.
mcp_servers:
  - name: sentry
    type: url
    url: https://mcp.sentry.dev/mcp
tools:
  - type: agent_toolset_20260401
    default_config:
      permission_policy: { type: always_ask }
    configs:
      - name: bash
        permission_policy: { type: always_ask }
  - type: mcp_toolset
    mcp_server_name: sentry
metadata:
  template: incident-commander

इसे load करें और जाँचें कि यह सही ढंग से store हुआ है या नहीं:

sandbase reload
sandbase list
sandbase chat agent_assistant --message "hello"

reload seed YAML को SQLite में import करता है। list को अब agent को एक ID के साथ print करना चाहिए। यदि list इसे नहीं दिखाता है, तो file parse नहीं हुई है, और .managed-agents/logs/runtime.log वह स्थान है जहाँ इसका कारण लिखा होता है।

mcp_servers MCP (model context protocol) endpoints को declare करता है। type: url का अर्थ है कि runtime किसी अन्य स्थान पर चल रहे server से HTTP के माध्यम से बात करता है, इसलिए आप जो कुछ भी पहले से operate कर रहे हैं, वह यहाँ काम करता है, जिसमें runtime के साथ उसी VPS पर hosted MCP servers भी शामिल हैं।

Server को declare करने मात्र से उसके tools agent को नहीं मिलते। tools list यह काम करती है, एक mcp_toolset entry के माध्यम से जिसका mcp_server_name ऊपर दिए गए name से मेल खाता है। यदि agent ऐसा व्यवहार करता है जैसे MCP tools मौजूद ही नहीं हैं, तो कहीं और देखने से पहले उन दोनों strings की अक्षर-दर-अक्षर तुलना करें।

agent_toolset_20260401 built-in tool set है। दिनांकित suffix एक schema version है, इसलिए इससे pin किया गया agent उन tool definitions को बनाए रखता है जिनके आधार पर उसे लिखा गया था। default_config set में मौजूद हर tool के लिए policy निर्धारित करता है, और configs के अंतर्गत प्रत्येक entry नाम के आधार पर एक tool को override करती है, जैसे उदाहरण में bash

permission_policy वह स्थान है जहाँ एक runtime bare model call की तुलना में अपनी उपयोगिता सिद्ध करता है। always_ask session को pause कर देता है और call के run होने से पहले human approval की प्रतीक्षा करता है। always_allow इसे अनुमति देता है। bash को always_ask पर set करने का अर्थ है कि agent आपके द्वारा सटीक command को पहले देखे बिना shell command run नहीं कर सकता, जो कि वही नियंत्रण है जिसे आप VPS पर सुरक्षित रूप से Claude Code run करते समय अपनाएंगे।

तीन सैंडबॉक्स मोड, और प्रत्येक का उपयोग कब करें

कोड निष्पादित करने वाले टूल कॉल एक सैंडबॉक्स के भीतर चलते हैं। बैकएंड का चयन प्रति वातावरण किया जाता है, जो वातावरण के config ऑब्जेक्ट में sandbox_provider के माध्यम से, या कंसोल में Settings के अंतर्गत Sandbox में होता है। वातावरण POST /v1/environments पर API के माध्यम से बनाए जाते हैं।

local कोड को रनटाइम की एक चाइल्ड प्रोसेस के रूप में, होस्ट पर, रनटाइम के स्वयं के उपयोगकर्ता के रूप में चलाता है। यह डिफ़ॉल्ट है, और यह तब उचित है जब आप एकमात्र उपयोगकर्ता हों और एजेंट केवल उन फ़ाइलों को पढ़ता है जिनके आप स्वामी हैं। यह आइसोलेशन नहीं है। एक टूल कॉल जो फ़ाइलों को हटाता है, वह आपकी फ़ाइलों को हटा देता है, और एक टूल कॉल जो /etc/sandbase/runtime.env को पढ़ता है, वह आपकी प्रदाता कुंजी (provider key) को पढ़ लेता है।

docker प्रति सत्र एक कंटेनर शुरू करता है।

{
  "sandbox_provider": "docker",
  "image": "node:22-slim",
  "resources": { "memory": "1g", "cpu": 1 }
}

सत्र को अपना स्वयं का फ़ाइल सिस्टम, अपनी मेमोरी सीमा और अपना CPU शेयर मिलता है, और सत्र के साथ कंटेनर को हटा दिया जाता है। जैसे ही कोई एजेंट ऐसा कोड चलाता है जिसे आपने नहीं लिखा है, इस मोड पर स्विच करें। इसकी लागत यह है कि रनटाइम के उपयोगकर्ता को Docker सॉकेट तक पहुंच की आवश्यकता होती है, और docker समूह की सदस्यता होस्ट पर root के बराबर होती है। प्रति-सत्र कंटेनर प्रति रन एक कंटेनर वाले सेल्फ-होस्टेड एजेंट सैंडबॉक्स के समान ही होते हैं, इसलिए एक एस्केप्ड प्रोसेस क्या एक्सेस कर सकती है, इस बारे में तर्क यहाँ अपरिवर्तित लागू होता है।

kubernetes सत्र वर्कलोड को एक पॉड के रूप में चलाता है और इसे kubectl exec और kubectl cp के साथ संचालित करता है। रनटाइम इमेज में kubectl का होना आवश्यक है, और इसके ServiceAccount को लक्षित नेमस्पेस में पॉड्स को बनाने, हटाने, प्राप्त करने, सूचीबद्ध करने और देखने के लिए RBAC (role-based access control) अनुमति की आवश्यकता होती है, साथ ही exec सब-रिसोर्स की भी आवश्यकता होती है। यह मोड सेटअप करने के लायक तभी है यदि आप पहले से ही एक क्लस्टर चला रहे हैं।

Runtime को 127.0.0.1 पर क्यों bind किया गया है?

ऐसा इसलिए है क्योंकि यह authentication बंद होने पर शुरू होता है। जब कम से कम एक API key मौजूद होती है, तो runtime bearer-token authentication को सक्षम कर देता है, लेकिन एक नया init कोई key नहीं बनाता है। यदि इसे उस default पर 0.0.0.0 पर bind कर दिया जाए, तो एक unauthenticated agent runtime, जिसमें shell tools और आपका provider key मौजूद है, public internet पर expose हो जाएगा।

इसलिए जब आप इसे सुलभ बनाना चाहते हैं, तो bind address को न बदलें और दो अन्य कार्य करें।

सबसे पहले, authentication को चालू करें। service environment file में MANAGED_AGENTS_API_KEY सेट करें, या POST /v1/api-keys के साथ एक key बनाएँ, जो एक बार secret_key field लौटाती है और उसे दोबारा कभी नहीं दिखाती है। इसके बाद clients हर request पर Authorization: Bearer <key> भेजते हैं।

दूसरा, सामने एक reverse proxy लगाएँ और वहाँ TLS (transport layer security) terminate करें। runtime को design के अनुसार plain HTTP serve करने के लिए बनाया गया है और यह अपेक्षा करता है कि certificates को संभालने का काम कोई और करे।

server {
    listen 443 ssl;
    server_name agents.example.com;

    ssl_certificate     /etc/letsencrypt/live/agents.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/agents.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

उनमें से दो lines केवल सजावट नहीं हैं। proxy_buffering off महत्वपूर्ण है क्योंकि sessions server-sent events (SSE) पर stream होते हैं, और buffering चालू होने पर, nginx response को तब तक रोक कर रखता है जब तक कि उसका buffer भर न जाए। इस कारण console पर कुछ भी दिखाई नहीं देता जबकि agent काम कर रहा होता है, और अंत में सब कुछ एक साथ dump हो जाता है। proxy_read_timeout 3600s महत्वपूर्ण है क्योंकि default समय 60 seconds है, इसलिए यदि कोई stream एक minute से अधिक समय तक शांत रहती है, तो proxy उसे बीच में ही बंद कर देता है, और यह विफलता runtime के क्रैश होने जैसी लगती है।

Firewall पर, 22 और 443 ports खोलें। 3000 को बंद रखें, क्योंकि proxy इसे loopback के माध्यम से access करता है और box के बाहर से किसी को भी इसे access नहीं करना चाहिए।

Anthropic SDK को अपने सर्वर की ओर निर्देशित करें

Runtime एक CMA-आकार की /v1 सतह लागू करता है, इसलिए एक Anthropic SDK क्लाइंट एक फ़ील्ड बदलकर इससे संवाद करता है।

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.MANAGED_AGENTS_API_KEY ?? 'local-dev-key',
  baseURL: 'http://127.0.0.1:3000'
});

यह उन बीटा हेडर को भी स्वीकार करता है जिन्हें Claude Managed Agents क्लाइंट भेजते हैं, anthropic-beta: managed-agents-2026-04-01 और anthropic-beta: agent-memory-2026-07-22। एक स्थानीय runtime के विरुद्ध ये वैकल्पिक हैं। ये इसलिए मौजूद हैं ताकि होस्ट किए गए डिप्लॉयमेंट के लिए लिखा गया कोड यहाँ बिना किसी बदलाव के चल सके।

संगतता काफी हद तक है, लेकिन पूर्ण नहीं है। किसी सतह के अस्तित्व को मानने से पहले चेकआउट में docs/api-matrix.md पढ़ें, क्योंकि प्रोजेक्ट वहां अपनी कमियों का दस्तावेजीकरण करता है, जिसमें क्लाइंट-साइड कस्टम टूल्स भी शामिल हैं, जिन्हें अभी भी वर्तमान इवेंट-रिजल्ट प्रोटोकॉल के ऊपर नामित पंजीकरण की आवश्यकता है।

Plain HTTP भी उतना ही अच्छा काम करता है, और यह साबित करने का सबसे तेज़ तरीका है कि runtime सक्रिय है:

curl -N -X POST http://127.0.0.1:3000/v1/sessions/SESSION_ID/messages \
  -H "Content-Type: application/json" \
  -d '{"content": "Hello", "stream": true}'

एक स्वस्थ प्रतिक्रिया इवेंट्स की एक ऐसी स्ट्रीम है जो लगातार आती रहती है। यदि कनेक्शन टूट जाता है, तो पूरे टर्न को फिर से चलाने के बजाय उस अंतिम इवेंट से फिर से शुरू करें जिसे आपने देखा था:

curl -N http://127.0.0.1:3000/v1/sessions/SESSION_ID/events/stream \
  -H "Last-Event-ID: EVENT_ID"

वह रिज्यूमेबल स्ट्रीम ही कारण है कि एक सेशन बंद लैपटॉप के बाद भी जीवित रहता है। इवेंट्स सर्वर पर सुरक्षित रहते हैं, इसलिए क्लाइंट केवल एकमात्र कॉपी रखने के बजाय एक लॉग को फिर से चला रहा होता है।

जहाँ क्रेडेंशियल्स, मेमोरी और ऑडिट ट्रेल्स डिस्क पर रहते हैं

रनटाइम के स्वामित्व वाली हर चीज़ वर्कस्पेस में .managed-agents/ के अंतर्गत होती है।

.managed-agents/
├── config.yaml
├── data.db
├── logs/runtime.log
├── files/
├── skills/
├── snapshots/
└── sandbox/
  • data.db SQLite मेटाडेटा है: एजेंट्स, सेशंस, क्रेडेंशियल वॉल्ट एंट्रीज, मेमोरी स्टोर एंट्रीज और API कीज़।
  • files/ में अपलोड की गई फाइल बाइट्स होती हैं और skills/ में अपलोड किए गए स्किल पैकेज होते हैं।
  • snapshots/ में सेशन वर्कस्पेस स्नैपशॉट्स होते हैं, और sandbox/ में लोकल-मोड सेशंस की वर्किंग डायरेक्टरीज होती हैं।
  • logs/runtime.log वह पहली जगह है जहाँ तब देखें जब कुछ भी बिना किसी संकेत के काम न कर रहा हो।

क्रेडेंशियल वॉल्ट्स सीक्रेट्स के समूह होते हैं, जिन्हें प्रत्येक को auth_type जैसे कि environment_variable के साथ जोड़ा जाता है, और सेशन बनाते समय vault_ids के माध्यम से सेशन से अटैच किया जाता है। मेमोरी स्टोर्स में नामित एंट्रीज होती हैं जिन्हें आप अपनी एक्सेस सेटिंग और निर्देशों के साथ memory_store के रूप में सेशन में माउंट करते हैं। दोनों data.db में रहते हैं, जो कि रॉ मॉडल कॉल और इसके बीच का वास्तविक अंतर है: रनटाइम सेशंस के बीच याद रखता है, और यह जो हुआ उसे लिख लेता है।

चूंकि यह एक ही डायरेक्टरी है, इसलिए इसका बैकअप एक साथ लें।

sudo systemctl stop sandbase
sudo tar czf /root/sandbase-$(date +%F).tgz -C /opt/sandbase/workspace .managed-agents
sudo systemctl start sandbase

सबसे पहले सर्विस को रोकें। रनटाइम के लिखते समय SQLite डेटाबेस को कॉपी करने से ऐसी फाइल कैप्चर हो सकती है जो रिस्टोर करने पर खुलेगी नहीं, और आपको इसका पता उस दिन चलेगा जब आपको इसकी आवश्यकता होगी। यदि आप एजेंट YAML को git में और स्टेट को कहीं और रखना चाहते हैं, तो डिप्लॉयमेंट डॉक start पर --data-dir के साथ स्टेट लोकेशन को पिन करने का समर्थन करता है।

रिस्टोर करना इसका उल्टा है: एक नए बॉक्स पर उसी टैग को चेक आउट करें, आर्काइव को वर्कस्पेस में अनपैक करें, सर्विस स्टार्ट करें। यदि आपने ${OPENAI_API_KEY} फॉर्म का उपयोग किया है तो आपका प्रोवाइडर की आर्काइव में नहीं होगा, इसलिए उसे कहीं ऐसी जगह रखें जहाँ वह आपके पास सुरक्षित रहे।

इसे systemd के अंतर्गत चलाएं

Runtime को अपना एक अलग user दें ताकि local sandbox mode में कोई tool call आपके user के रूप में कार्य न कर सके।

sudo adduser --system --group --no-create-home --home /opt/sandbase sandbase
sudo chown -R sandbase:sandbase /opt/sandbase

इसे /etc/systemd/system/sandbase.service के रूप में save करें।

[Unit]
Description=SandBase Harness runtime
After=network-online.target

[Service]
User=sandbase
Group=sandbase
WorkingDirectory=/opt/sandbase/workspace
EnvironmentFile=/etc/sandbase/runtime.env
ExecStart=/usr/bin/node /opt/sandbase/sandbase-harness/dist/index.js start --host 127.0.0.1 --port 3000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Project का अपना deployment उदाहरण PATH पर एक managed-agents binary को call करता है। Tagged-source install इसे create नहीं करता है, इसलिए ExecStart इसके बजाय built entry point के विरुद्ध node चलाता है।

sudo systemctl daemon-reload
sudo systemctl enable --now sandbase
sudo systemctl status sandbase
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/dashboard

एक सही परिणाम status से active (running) और curl से 200 है। यदि कुछ और दिखाई दे, तो पहले journalctl -u sandbase -n 50 और फिर .managed-agents/logs/runtime.log पढ़ें। enable --now वह हिस्सा है जो मायने रखता है, क्योंकि हाथ से start की गई process अगले reboot के बाद समाप्त हो जाती है।

क्या खराब होता है और आपको क्या संदेश दिखाई देगा

npm run build बिना किसी npm error के बंद हो जाता है। 1 GB के VPS पर TypeScript compile प्रक्रिया को kernel का out-of-memory killer रोक देता है, जो इसे npm के बजाय kernel log में रिपोर्ट करता है। इसकी पुष्टि journalctl -k | grep -i "out of memory" से करें, जो उस killed node प्रक्रिया का नाम बताने वाली एक लाइन प्रिंट करेगा। Swap जोड़ें, या किसी बड़े instance पर build करें और dist/ को कॉपी करें।

Error: listen EADDRINUSE: address already in use 127.0.0.1:3000 कोई अन्य प्रक्रिया पहले से ही उस port का उपयोग कर रही है। sudo ss -lntp | grep 3000 उसका नाम बताता है। या तो उस प्रक्रिया को रोकें या --port 3001 के साथ runtime शुरू करें और proxy को अपडेट करें।

Dashboard आपके laptop से लोड नहीं होगा। यह अपेक्षित व्यवहार है, क्योंकि runtime loopback पर bind होता है। ऊपर दिए गए SSH tunnel का उपयोग करें, या reverse proxy का काम पूरा करें। इसे --host 0.0.0.0 से ठीक न करें, क्योंकि जब तक key मौजूद नहीं होती, authentication बंद रहता है।

Docker sandboxes permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock के साथ विफल हो जाते हैं। sandbase user, docker group में नहीं है। इसे sudo usermod -aG docker sandbase के साथ ठीक करें और service को restart करें। यह समझें कि आपने क्या अनुमति दी है: वह group host पर root होता है, इसलिए यह उस कारण का एक हिस्सा खत्म कर देता है जिसके लिए आपने runtime को उसका अपना user दिया था।

Kubernetes sandboxes Error from server (Forbidden) के साथ विफल हो जाते हैं। ServiceAccount में pod permissions या exec subresource की कमी है। इसे सीधे kubectl auth can-i create pods/exec -n <namespace> के साथ जांचें, जो yes या no का उत्तर देता है।

API key जोड़ने के बाद हर request 401 return करती है। पहली key मौजूद होने पर authentication चालू हो जाता है, और यह API के साथ-साथ console पर भी लागू होता है। Authorization: Bearer <key> भेजें, और यदि आप key खो चुके हैं, तो दूसरी बनाएं, क्योंकि secret_key केवल एक बार return किया जाता है और इसे पठनीय रूप में store नहीं किया जाता है।

MCP server के tools session में कभी दिखाई नहीं देते। tools block में मौजूद mcp_server_name की तुलना mcp_servers में मौजूद name से करें, फिर जांचें कि क्या runtime सर्वर से ही उस URL तक पहुँच सकता है, इसके लिए curl -i <url> का उपयोग करें। URL-प्रकार का MCP server एक network dependency है, और एक VPS आपके laptop की तुलना में अलग तरह से names resolve करता है और traffic route करता है।

FAQ

क्या मैं OpenAI या Anthropic key के बिना SandBase Harness चला सकता हूँ?

हाँ, यदि आपके पास OpenAI-compatible endpoint है। Runtime, OpenAI, Anthropic और OpenAI-compatible providers का समर्थन करता है, इसलिए OpenAI API का उपयोग करने वाला कोई भी local server काम करेगा। .managed-agents/config.yaml में workspace provider सेट करें और api_key तथा endpoint को उस पर point करें। Runtime में अपना कोई model शामिल नहीं है, इसलिए calls का उत्तर देने के लिए किसी अन्य स्रोत की आवश्यकता होती है।

क्या runtime को public port पर expose करना सुरक्षित है?

डिफ़ॉल्ट इंस्टॉलेशन के अनुसार नहीं। यह 127.0.0.1:3000 पर bind होता है और authentication बंद होने के साथ शुरू होता है, और इसका समाधान केवल bind address बदलना नहीं है। एक API key बनाएँ, या MANAGED_AGENTS_API_KEY सेट करें, ताकि bearer-token authentication चालू हो सके। इसके बाद TLS के लिए nginx या Caddy को सामने रखें, और firewall पर port 3000 को बंद रखें ताकि अंदर आने का एकमात्र रास्ता proxy के माध्यम से ही हो।

local, Docker और Kubernetes sandboxes में क्या अंतर है?

local टूल कोड को host पर runtime के child process के रूप में चलाता है, जिसमें runtime user की अनुमतियाँ होती हैं और कोई isolation नहीं होता। docker प्रत्येक session को उसका अपना container देता है, जिसमें उसका अपना filesystem, memory limit और CPU share होता है, और session समाप्त होने पर वह उसे हटा देता है। kubernetes session को pod के रूप में चलाता है और इसे kubectl exec के साथ संचालित करता है, जिसके लिए runtime image के अंदर kubectl और target namespace में pods पर RBAC के साथ-साथ exec subresource की आवश्यकता होती है।

मुझे वास्तव में किसका बैकअप लेने की आवश्यकता है?

Workspace में स्थित .managed-agents/ directory का। इसमें config.yaml, agents, sessions, credential vault entries और memory entries के साथ data.db SQLite database, तथा upload की गई फाइलें, skill packages और session snapshots होते हैं। कॉपी करने से पहले service को रोक दें ताकि archive के दौरान SQLite में कोई डेटा न लिखा जाए। ${OPENAI_API_KEY} के रूप में संदर्भित Provider API keys बैकअप के अंदर नहीं होती हैं, इसलिए उन्हें अलग से सुरक्षित रखें।

main के बजाय v0.3.2 tag को clone क्यों करें?

Tag एक निश्चित tree है, इसलिए जिन config keys और CLI commands के बारे में आप पढ़ते हैं, वे वही हैं जो आपको वास्तव में प्राप्त होते हैं। main में बदलाव होते रहते हैं, और गाइड लिखे जाने तथा आपके द्वारा उसे चलाने के बीच config key का नाम बदला जा सकता है। प्रोजेक्ट यह भी चेतावनी देता है कि npm पर unscoped managed-agents पैकेज यह प्रोजेक्ट नहीं है, इसलिए npx managed-agents कुछ असंबंधित इंस्टॉल कर देगा। Release v0.3.1 मुख्य रूप से उस npm quick start को pinned tagged-source path से बदलने के लिए मौजूद है।