https://www.danscodellaro.com/api/agent/run
Dan Scodellaro Server Agent
AI agent that reads and writes Salesforce data. Send {"message": "..."} and receive a plain-English response.
Header — X-API-Key: dsk_<token>
POST
{"message": "{{user_message}}"}
response
{"ok": true, "response": "..."} — map the response field to the Moveworks reply.repo and read:user. The agent uses this to list repos, issues, and commits.| Time | User | Message | Response | Agent | s | Status |
|---|
Drag agents up or down to set the fallback order. The agent at the top is tried first; if it hits an error or usage limit, the next one takes over. Disabled agents are skipped.
Plain-English messages from Moveworks are routed through the agent fallback chain — each agent tries in priority order, falling through on error or usage limits. Agent order and available tools are loaded live from the server.
{
"system": "danscodellaro.com Moveworks Agent",
"description": "Natural-language API bridge. Plain-English requests from Moveworks are routed to Claude/Codex agents running in bypassPermissions mode. Agents autonomously call backend APIs (Salesforce, VPN) using a server-side service token, then return a formatted response.",
"version": "1.0",
"entrypoint": {
"url": "https://www.danscodellaro.com/api/agent/run",
"method": "POST",
"auth": {
"type": "api_key",
"header": "X-API-Key",
"format": "dsk_<token>",
"alternatives": ["session_cookie (same-origin)", "Authorization: Bearer dsk_<token>"]
},
"request": {
"content_type": "application/json",
"note": "Content-Type header is optional — server parses body with force=True",
"body": { "message": "string — natural language query; empty = connection ping" }
},
"response": {
"success": { "ok": true, "response": "string — answer in plain text or markdown" },
"error": { "ok": false, "error": "string — error description" },
"ping": { "ok": true, "response": "Connection is working" }
},
"guards": [
"HTTP 400 — message contains unsubstituted {{template}} variables",
"HTTP 401 — no valid auth provided"
]
},
"agent_chain": {
"description": "Agents tried in priority order; first non-empty response wins. Falls through on error or empty output.",
"permission_mode": "bypassPermissions — agents execute bash/curl without user confirmation prompts",
"auth_mechanism": "Service token (dsk_xxx) written to .agent-token file on disk at runtime. Agents read it via TOKEN=$(cat /path/.agent-token) to avoid Claude prompt-injection detection.",
"agents": [
{ "priority": 1, "id": "claude-y", "model": "claude-haiku-4-5-20251001", "binary": "/usr/local/bin/claude-y" },
{ "priority": 2, "id": "claude-x", "model": "claude-haiku-4-5-20251001", "binary": "/usr/local/bin/claude-x" },
{ "priority": 3, "id": "codex", "model": null, "binary": "codex (resolved via PATH)" }
]
},
"tools": {
"salesforce": {
"note": "OAuth access token managed server-side. Agents authenticate to these endpoints using the service token via X-API-Key header.",
"record_url_pattern": "{instance_url}/lightning/r/{ObjectType}/{RecordId}/view",
"endpoints": [
{ "method": "GET", "path": "/api/salesforce/query", "params": { "q": "SOQL string" },
"desc": "Run a read-only SOQL query against the connected org" },
{ "method": "POST", "path": "/api/salesforce/rest",
"body": { "method": "GET|POST|PATCH|DELETE", "path": "string e.g. /sobjects/Account/", "body": "object (optional)" },
"desc": "Proxy any Salesforce REST API call — supports reads and writes" },
{ "method": "GET", "path": "/api/salesforce/test",
"desc": "Return the connected Salesforce user identity and org info" }
]
},
"vpn": {
"management_url": "https://www.danscodellaro.com/vpn.html",
"endpoints": [
{ "method": "GET", "path": "/api/actions/vpn/instances",
"desc": "List all active VPN node instances" },
{ "method": "GET", "path": "/api/actions/vpn/regions",
"desc": "List available regions for VPN node deployment" },
{ "method": "POST", "path": "/api/actions/vpn/start",
"body": { "region": "string e.g. ap-southeast-2" },
"desc": "Provision a new VPN node in the specified region" },
{ "method": "POST", "path": "/api/actions/vpn/{instance_id}/stop",
"desc": "Terminate a running VPN node by instance ID" },
{ "method": "GET", "path": "/api/actions/vpn/sessions",
"desc": "Retrieve historical VPN session records" }
]
}
},
"observability": {
"method": "GET",
"path": "/api/agent/logs",
"auth": "Same as /api/agent/run (X-API-Key or session)",
"params": { "limit": "integer, default 100" },
"response_fields": ["created_at", "user_email", "message", "response", "error", "agent_used", "duration_ms", "ok"]
},
"extending": {
"add_new_tool": "Add the endpoint to _agent_system_prompt() in api/server.py. Document: HTTP method, full URL with base domain, request body schema, and a usage example. Keep descriptions terse — the system prompt is token-constrained.",
"add_new_agent": "Add an entry to CLAUDE_ACCOUNTS (or equivalent) in api/agent_console.py. Then insert it into _AGENT_PRIORITY list in the agent_run() route in api/server.py.",
"service_tokens": "Tokens are dsk_-prefixed strings. Generated and cached by _agent_get_service_token() in api/server.py; stored in config.json['agent_service_token']. Any valid dsk_ token from the users DB also works."
}
}
System prompt sent to the agent on every request. Read-only — edit _agent_system_prompt() in api/server.py to change. Token file path is redacted.
Loading…