# Connect an agent

Install `.[mcp]` from the project root, or install the supplied wheel with its `mcp` extra. The protocol integration uses the official MCP Python SDK 1.x, tested with version 1.29.0. The dependency range excludes the SDK's different version 2 API.

Configure your host with the executable `atlas-upstream-mcp` and arguments `--workspace` and an absolute project directory. A conventional JSON host configuration is shown below. Replace the example directory with the actual project path and use your host's configuration location.

```json
{
  "mcpServers": {
    "atlas-upstream": {
      "command": "atlas-upstream-mcp",
      "args": ["--workspace", "/absolute/path/to/project/.upstream"]
    }
  }
}
```

The host must be able to resolve the executable in the environment where the package was installed. An absolute executable path is suitable for a virtual environment. The server's standard output carries protocol traffic. Diagnostics use standard error.

## First exchange

Call `template` with the following arguments.

```json
{
  "objective": "Deliver the approved report to its reader.",
  "stages": ["draft", "published"],
  "instructions": ["Publish the approved report to the agreed location."],
  "success_question": "Can a separate reader retrieve the approved bytes?",
  "principal": "editor",
  "operator": "publisher",
  "observer": "reader"
}
```

Inspect the returned mission, then pass it to `create` with a stable `mission_id`, such as `report-november`. The template uses one-hour freshness, an initial one-second action estimate and a budget of 300 weighted units. Adapt those values for the task. The chosen person or adapter must have the authority and observation capability represented by its source label.

Once the editor has authorised publication and the publisher has observed the draft, call `record`.

```json
{
  "mission_id": "report-november",
  "revision": 0,
  "events": [
    {"id": "editor-authority", "kind": "observe", "fact": "requested", "value": "published", "source": "editor", "evidence": "Editor authorised the agreed report."},
    {"id": "draft-seen", "kind": "observe", "fact": "stage", "value": "draft", "source": "publisher", "evidence": "The approved draft is present."}
  ]
}
```

Use those statements only when they describe observations from your actual task. Read `snapshot`. If its decision is `act`, record a `begin` event before the external operation. After the operation, record the position observation and the `end` event with the begin ID. On reaching the final stage, Upstream requests a receiving observation. If the observer reports `needs-work`, it recommends repair. A fresh positive receipt permits completion.

## Survive a lost response

Use stable event IDs. If a record response is lost, resend the identical batch with its original revision. Automatic timestamps from the first write are retained on retry. The entire batch either commits or rolls back. Another writer changing the journal causes a stale-revision error. Recover with `snapshot` before proposing more work.

An open `begin` survives a restart. Inspect the external operation before closing or retrying it. The local journal cannot make an external device or service execute exactly once. A tool supporting idempotency keys should receive the begin event's ID.

Automatic time uses fractional Unix seconds. Existing integer mission clocks remain supported through explicit `at` values. Keep one clock convention per mission. Supply `observed_at` for evidence acquired earlier. A stale observation retains its actual age. Clock regressions cause a validation error so the host can reconcile them.

## Learn with evidence

Call `lesson` after verified completion. The `context` and expected `checks` are your labels. The returned practice case records those labels, the supporting observations and a journal digest. Review the `cases` array before importing it into Opsbook. Add separately labelled examples and controls before evaluating a proposed instruction. This interface exports data to the calling host. Review its content before sharing.

## Implementation references

The official SDK handles negotiation, request validation and stdio transport. The integration test uses the official client to discover the schemas, reject an incomplete event, complete a real file task and resume after a server restart.

- [MCP lifecycle specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle)
- [MCP tools and structured results](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)
- [Official Python SDK](https://github.com/modelcontextprotocol/python-sdk)
