# Claude → Solid: feature development integration

Give Claude a task, let a Solid agent implement it, then bring the result back.
Verified against this workspace’s authenticated live OpenAPI specification on September 14, 2026. This is a workspace-specific integration guide, not a claim that Solid ships an official Claude plugin or MCP server.

## 1. Paste this into Claude

```text
Integrate with my Solid workspace using this guide:
https://spacesheep.dev/@misha/claude-solid-integration

Read guide.md and use the provided solid_client.py CLI. I will supply the private
solid.env file separately; never print its token, commit it, or send it to any
service except the documented Solid API and documentation URLs.

When I ask “Make Solid develop a feature,” write a detailed prompt with the repo,
base branch, feature, acceptance criteria, and allowed delivery actions. Create a
fresh Solid agent using the CLI. Save the state file and acceptance receipt. Poll
until the run finishes, retrieve the messages, and summarize the changes, tests,
blockers, and artifact links. Keep incomplete requests resumable. A failed or
interrupted run is not a successful feature implementation. If the agent reports
that it needs input, relay that question to me.

For uncertain submissions, retry the existing state file with the same request
and Idempotency-Key. Do not create a replacement task. Do not merge or deploy
unless I ask for those actions. Keep each task’s state files separate.
```

Claude Code or another Claude host needs a shell with Python 3.9+ and outbound HTTPS. A chat-only Claude interface needs a tool host or connector; pasting this document alone does not grant API execution.

## 2. Environment variables

Download the private **solid.env** from the Solid conversation separately. It contains the actual workspace token. The public template below deliberately contains a placeholder.

```bash
export SOLID_WORKSPACE_API_URL='https://solid.tech/api/workspace'
export SOLID_WORKSPACE_API_SPEC_URL='https://solid.tech/api/workspace-docs/openapi.json'
export SOLID_WORKSPACE_API_TOKEN='REPLACE_WITH_PRIVATE_WORKSPACE_TOKEN'
export SOLID_SENDER_AGENT_ID='3wGWvt'
export SOLID_TARGET_AGENT_ID='3wGWvt'
```

| Variable | Role |
| --- | --- |
| SOLID_WORKSPACE_API_URL | API base; already includes `/api/workspace`. |
| SOLID_WORKSPACE_API_SPEC_URL | Live OpenAPI document; requires the same bearer token. |
| SOLID_WORKSPACE_API_TOKEN | Workspace-wide credential, supplied privately. It is broader than a feature-only API key. |
| SOLID_SENDER_AGENT_ID | Helper variable for request attribution. `3wGWvt` is the existing “Solid agent integration” conversation. |
| SOLID_TARGET_AGENT_ID | Helper variable for messages to that existing conversation; unused when creating a fresh task agent. |

`SOLID_SENDER_AGENT_ID` and `SOLID_TARGET_AGENT_ID` are conventions used by this guide, not automatically provisioned platform variables. Solid agents already receive `SOLID_AGENT_ID` in their runtime. Claude outside Solid does not have a native Solid ID; these examples attribute its requests to the existing integration agent. Both sender and target must be in the authenticated workspace. You can substitute another existing agent ID from `GET /agents`.

Put the private file outside your repository, for example `~/.config/solid/solid.env`, then load it in the shell that runs the CLI:

```bash
chmod 600 ~/.config/solid/solid.env
source ~/.config/solid/solid.env
```

The workspace token is already provisioned in Solid’s environment; this guide does not assume an unverified API-key creation screen. No Spacesheep key or Anthropic API key is needed by this helper. Claude’s own host manages its Claude authentication.

## 3. Connect your local Claude agent

### Connect your local Claude Code

These commands are for macOS, Linux, or WSL, using Bash or Zsh. Install and sign in to Claude Code first if it is not already working; see [Anthropic’s official quickstart](https://code.claude.com/docs/en/quickstart). Native Windows users can run this workflow inside WSL.

1. Download the private `solid.env` attachment from this Solid conversation to your local computer. Create a credential folder and move that download into it. Adjust the source path if your browser used a different filename:

```bash
mkdir -p ~/.config/solid
chmod 700 ~/.config/solid
mv ~/Downloads/solid.env ~/.config/solid/solid.env
chmod 600 ~/.config/solid/solid.env
```

2. Download the helper and guide to a local tool folder. These URLs serve raw files and do not require a Spacesheep login:

```bash
mkdir -p ~/.local/share/solid-claude
cd ~/.local/share/solid-claude
curl -fL 'https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/solid_client.py' -o solid_client.py
curl -fL 'https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/guide.md' -o guide.md
curl -fL 'https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/feature.txt' -o feature.txt
python3 solid_client.py --help
```

3. Load the private environment and verify the connection before creating any task:

```bash
source ~/.config/solid/solid.env
curl --fail-with-body --silent --show-error \
  -H "Authorization: Bearer $SOLID_WORKSPACE_API_TOKEN" \
  "$SOLID_WORKSPACE_API_URL/context"
```

A successful response is workspace identity JSON, not an HTML login screen. Do not run `env`, `printenv`, or shell tracing to debug the credential. If Claude later reports a missing variable, source the file in the same shell command that invokes the helper, or restart Claude from the configured terminal.

4. Open Claude Code in your repository, launched from that configured shell:

```bash
cd /path/to/your/repository
claude
```

Paste the handoff prompt in section 1. Also tell Claude: “The helper and guide are in `~/.local/share/solid-claude/`. Load `~/.config/solid/solid.env` when invoking the helper. Keep task state files in `~/.local/share/solid-claude/tasks/`. Read the guide before making API calls.” Claude’s existing command permissions still apply; this setup does not bypass them. No MCP configuration or incoming port is required for the shell workflow.

5. To make the behavior persistent for this project, append the following to its existing `CLAUDE.md` without replacing other instructions. Claude Code reads project instructions from this file; see [Anthropic’s memory documentation](https://code.claude.com/docs/en/memory).

```text
Solid delegation instructions:
When I explicitly ask Solid to develop a feature, use the local helper at
~/.local/share/solid-claude/solid_client.py. Read the accompanying guide.md.
Load ~/.config/solid/solid.env in the helper's shell; never print or commit it.
Create a fresh task agent by default. Put prompt and unique request state files
in ~/.local/share/solid-claude/tasks/. Include the remotely accessible repository,
base branch, acceptance criteria, and allowed delivery actions in the prompt.
Retain request state and receipt. For uncertain submissions, retry that state.
Poll and read the result. Report implementation, tests, links, and blockers.
Do not equate API acceptance or a completed conversation with tested success.
Do not merge or deploy unless I explicitly authorize it.
```

Now ask: **“Make Solid develop a feature: add CSV export to the reports page in REPO_URL. Use branch main, test the export, and return a branch or patch without deploying.”** Replace the example with your actual feature. Claude should submit through the helper, show you the returned Solid agent URL, then retrieve its results. This guide prepares the connection; it cannot install files on your local machine from the Solid workspace.

### Run the helper yourself

Files: [Python CLI](https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/solid_client.py), [environment template](https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/solid.env.example), [task template](https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/feature.txt), [this guide as Markdown](https://bc3d5632-5a93-43aa-aa88-9a1091a00e30.spacesheep.app/guide.md). Download them into a local working directory. Review the script before running it.

Edit `feature.txt` to replace the repository, branch, feature, and acceptance-criteria placeholders. The repository must be accessible from the Solid machine; a local path on your laptop does not automatically exist there.

```bash
# Load your private environment into this shell.
source ~/.config/solid/solid.env

# Start one feature task. Choose a new state filename for each task.
python3 solid_client.py start feature.txt --state feature-001.json

# Wait up to 30 minutes and save the result locally.
python3 solid_client.py wait feature-001.json --timeout 1800 > feature-001-result.json

# Inspect or resume later.
python3 solid_client.py status feature-001.json
python3 solid_client.py result feature-001.json

# Only if submission failed or its response was lost:
python3 solid_client.py retry feature-001.json

# Request interruption if you decide to stop the task.
python3 solid_client.py stop feature-001.json
```

The CLI uses only Python’s standard library. It stores the original request and UUID in `feature-001.json` before submitting, and the accepted agent summary in `feature-001.json.accepted.json`. Keep both. These files omit the token but may contain confidential task text. Use one CLI process per state file; concurrent writes to the same state are not supported.

`wait` checks every 10 seconds by default. Its exit codes are `0` for a completed run, `1` for failure/interruption or a client error, and `2` for a local wait timeout. A local timeout does not cancel Solid’s work: resume `wait` using the same state file. A failed run with a non-null `retry_at` is still awaiting scheduled recovery, so the helper continues waiting. Network errors stop the local command; rerun `wait` without submitting another task.

The result contains the agent summary and recorded runs in sequence order, including messages. It is not a guarantee that acceptance criteria were met: inspect the final report and tests. The archive can briefly lag completion; if results are empty or incomplete, fetch `result` again. Archived transcript data can be null and some payloads may be truncated.

## 4. The HTTP contract

Every request—including OpenAPI and GET requests—uses `Authorization: Bearer $SOLID_WORKSPACE_API_TOKEN`. JSON writes also use `Content-Type: application/json`.

| Method | Path relative to API base | Purpose |
| --- | --- | --- |
| GET | `/context` | Verify authentication and workspace identity. |
| GET | `/agents` | List agents, most recently active first. |
| POST | `/agents` | Create a fresh agent; returns `201` with an agent summary. |
| POST | `/agents/{id}/messages` | Send a follow-up or steer a run; returns `202`. |
| GET | `/agents/{id}` | Read latest status and recovery schedule. |
| GET | `/agents/{id}/runs` | Read run headers, newest first, up to 25 per page. |
| GET | `/agents/{id}/runs/{sequence}` | Read a recorded run and its messages. |
| POST | `/agents/{id}/stop` | Request interruption; no request body. |

Create and message operations take exactly this body:

```json
{
  "sender_agent_id": "3wGWvt",
  "text": "Implement FEATURE in REPOSITORY. Acceptance criteria: ..."
}
```

Text must be nonempty after trimming and at most 200,000 characters. Creation accepts an initial message asynchronously: `201` means the agent exists, not that the work is finished. Use the returned `id` for subsequent calls; do not assume the task ID is `3wGWvt`.

A message to an idle conversation starts a run. A message to a running conversation steers that run. A still-queued conversation may reject a message with `agent_message_rejected`. This is why the helper creates a fresh conversation per task instead of using the integration conversation for every feature.

Agent statuses are `idle`, `queued`, `running`, `completed`, `interrupted`, and `failed`. Status describes the latest run; it does not close the conversation permanently. New messages can start more runs. `retry_at` describes scheduled recovery. Stop cancels pending recovery and new input supersedes it.

For run history, pass a non-null `next_before_sequence` as the next request’s `before_sequence`; stop when it is null. Sequence numbers start at 1 within each agent. Do not assume the entire task lives in the newest run: continuation runs can contain later work. `messages` contains objects with `role` (`user`, `assistant`, or `agent`) and `text`.

## 5. Minimal curl examples

Verify access and retrieve the current schema:

```bash
curl --fail-with-body --silent --show-error \
  -H "Authorization: Bearer $SOLID_WORKSPACE_API_TOKEN" \
  "$SOLID_WORKSPACE_API_URL/context"

curl --fail-with-body --silent --show-error \
  -H "Authorization: Bearer $SOLID_WORKSPACE_API_TOKEN" \
  "$SOLID_WORKSPACE_API_SPEC_URL" -o solid-openapi.json
```

To send this existing integration agent a message, first save a request body and key. This Python block refuses to overwrite an existing request file:

```bash
python3 - <<'PY'
import json, os, uuid
with open('message.json', 'x') as f:
    json.dump({
        'sender_agent_id': os.environ['SOLID_SENDER_AGENT_ID'],
        'text': 'Develop feature X in repo Y. Acceptance criteria: ...'
    }, f)
with open('message.key', 'x') as f:
    f.write(str(uuid.uuid4()))
PY

curl --fail-with-body --silent --show-error \
  -H "Authorization: Bearer $SOLID_WORKSPACE_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(cat message.key)" \
  --data-binary @message.json \
  "$SOLID_WORKSPACE_API_URL/agents/$SOLID_TARGET_AGENT_ID/messages"
```

For a new agent, use the same body shape with `POST /agents` and a **new** key for that distinct operation. Never reuse `message.key` when changing the path or body. Prefer the provided CLI for reliable task creation and receipt storage.

## 6. Retries, results, and blockers

Choose a fresh random `Idempotency-Key` for each logical mutation and retain it. Retry an uncertain delivery with the same method, URL, body, input headers, and key. Keys are workspace-wide. Reusing a key for a changed request has undefined behavior; omitting a key starts a new operation on every request. A timeout does not prove the write failed. Do not bypass an uncertain failure with a new key.

| Symptom | What Claude should do |
| --- | --- |
| 400 | Read the problem `code`/`detail`; check JSON, text length, and parameters. |
| 401 / 403 | Check private token, authenticated workspace, and sender/target ownership. |
| 402 | Report the funding/resource blocker to the user. |
| 404 | Check the agent ID and resource path. |
| 409 / agent_message_rejected | Inspect current state; a queued conversation can reject messages. Preserve the request identity. |
| 5xx or POST timeout | Preserve saved state; reconcile/retry the identical request. Persistent failures may need operator repair. |
| Completed but asks for input | Relay the question; send the answer to that same task agent using `/messages`. |
| Failed / interrupted | Retrieve recorded runs and report the failure; inspect `retry_at` and `interruption_reason`. |

Final Markdown in the Solid conversation is not automatically sent back to the sender. External Claude should poll and read recorded messages as demonstrated. The inspected API does not expose a task-completion webhook registration operation. For Solid-to-Solid collaboration, explicitly ask the worker to message its sender with the result; for this external integration, polling is the implemented return path.

## 7. Give Solid enough context

A good request identifies the repo URL or workspace path, base branch, observable acceptance criteria, relevant files or architecture, test commands if known, and expected deliverable (branch, patch, draft PR, preview). State whether merges or deployments are authorized. Include an external task identifier in the prompt if Claude tracks jobs elsewhere.

Solid runs on a persistent shared Linux workspace. It can edit code, run commands and tests, and work with accessible repositories. Creating an agent creates a conversation on that same machine, not a separate VM. Concurrent agents must use separate branches/worktrees where appropriate. Repository credentials must be provisioned separately when needed; the Solid API token is not a GitHub credential.

For an existing-agent workflow, correlate messages and new run sequences carefully. A previously completed status can belong to an older task, and steering may enter a currently running conversation. The provided CLI avoids most of this ambiguity by creating a fresh task agent each time.

## 8. Optional tool or MCP wrapper

The downloadable CLI is a working shell integration. A custom tool host can expose three tools around it:

| Tool you implement | Underlying action |
| --- | --- |
| `solid_develop_feature(prompt)` | Save prompt; run `start`; return accepted agent ID and local state handle. |
| `solid_task_status(handle)` | Run `status`; return current status. |
| `solid_task_result(handle)` | Run `result`; return messages and artifact links. |

These names are proposed wrapper names, not built-in Solid or Claude tools. A wrapper should validate prompts, generate its own filenames, keep the workspace credential server-side, and preserve request state. For a remote or chat-only Claude host, an authenticated bridge in the Solid workspace could expose this narrower tool surface. No bridge, webhook receiver, or MCP server is deployed as part of this guide.

## 9. Credential boundaries and validation

The public Spacesheep page and downloads contain no token. The private environment attachment in Solid contains a live workspace-wide credential; keep it out of source control and public pages. Load it only into a trusted local shell/tool process. Do not paste its contents into the Spacesheep assistant or expose it as a browser-side environment variable. The Python helper rejects a changed API origin and does not follow redirects when sending credentials.

Validation for this guide: live schema inspection, an authenticated read-only workspace request, helper syntax and CLI checks, and mocked submission/retry/polling tests. No feature agent was launched solely to test the guide. A real development task still depends on funding, repository access, and a complete feature request.

Primary source: [Solid’s live OpenAPI specification](https://solid.tech/api/workspace-docs/openapi.json) (workspace bearer authentication required). The saved schema used for this guide is dated September 14, 2026; fetch the live schema if contract errors indicate changes.
