Skip to content

Let an agent work for you

An agent is a program — a notebook, a script or an AI assistant — that works in one project on your behalf. It never has more access than you: it reads what you can read, and every change it wants to make is shown to you first. Nothing about your own work needs an agent, and no model service or key is involved in Ophiolite itself.

In Settings → Agents, choose Add agent and decide:

  • Name — shown to you in approvals and the inbox.
  • May propose calculations, results and sharing — without it the agent can only read. It needs permission to edit this project.
  • Daily limits — how many calculation runs and publications per day.
  • Automatic approval — optionally let the agent’s calculation setups and runs go ahead without asking you. Publishing a result and changing who can see it always wait for you.
  • Expires after 1, 7 or 30 days.

The credential (oph_agent_…) is shown once; copy it into the agent’s configuration. Anyone holding it can act as the agent until you revoke it. Revoke an agent in the same table; its pending requests disappear from your inbox.

When the agent wants to change something, it proposes the exact request. You see it in Settings → Agents → Approvals and as an inbox update (An agent asks for your approval) with the agent’s name and its description. Approve allows exactly that request, once; the agent cannot change a value, a curve or a recipient afterwards without asking again. Decline ends it. Unanswered requests expire after 24 hours.

An agent may read 193 kinds of information you can read, ask you to approve 28 kinds of change, and make 5 more only as part of a request you approved. Everything else stays with people.

What the agent may doHow
Configure applicationNeeds your approval
Publish applicationNeeds your approval
Share applicationNeeds your approval
Start applicationNeeds your approval
Keep your saved mapping of a table of this project’s connection as a project layoutNeeds your approval
Keep a reviewed mapping as a layout, or a new version of oneNeeds your approval
Ask for a database to be added, without a sign-inNeeds your approval
Withdraw your own requestNeeds your approval
Deliver as an outcomeNeeds your approval
Report a run of an enabled procedure versionNeeds your approval
Register a procedure bundleNeeds your approval
Record that you trust the code of one procedure version in this projectNeeds your approval
Set who may read and reuse your derived publication, within its roots’ ceilingNeeds your approval
Make an exact result version againNeeds your approval
Cancel a queued or running jobNeeds your approval
Queue a script to complete one of your recorded runs in the sandboxed runnerNeeds your approval
Bind upstream sourceNeeds your approval
Mapping-save upstream sourceNeeds your approval
Say what an import of the input would do with a target and a mappingNeeds your approval
Read a table file for an importNeeds your approval
Start the reviewed importNeeds your approval
Run the next rows as the person who started the importNeeds your approval
Start a folder uploadNeeds your approval
Record that you accept or reject one exact result version, with your reasonNeeds your approval
Read a table of wells and say which rows become wells, which are already here and which are skipped, with reasonsNeeds your approval
Start the reviewed importNeeds your approval
Run the next rows as the person who started the import, each in its own transactionNeeds your approval
Create the listed wells as provisional wells and link every file that names them, or link to a well you have, in one stepNeeds your approval
Publish a file derived from exact revisions you may reuse, with its declared methodRuns as part of a request you approved
Declare what a read procedure made on your computer from a file that can be read on your computerRuns as part of a request you approved
The original of a conversion declared with keep_originalRuns as part of a request you approved
One file a read procedure madeRuns as part of a request you approved
One file of a folder uploadRuns as part of a request you approved
Technical reference
OperationHow
applications/configureNeeds your approval
applications/publishNeeds your approval
applications/shareNeeds your approval
applications/startNeeds your approval
layouts/keepNeeds your approval
layouts/saveNeeds your approval
org-connections/requestNeeds your approval
org-connections/request-withdrawNeeds your approval
outcomes/deliver-asNeeds your approval
procedure-runs/reportNeeds your approval
procedures/registerNeeds your approval
procedures/trustNeeds your approval
publications/shareNeeds your approval
results/remake-runNeeds your approval
runners/cancelNeeds your approval
runners/submitNeeds your approval
sources/bindNeeds your approval
sources/mapping-saveNeeds your approval
table-imports/previewNeeds your approval
table-imports/readNeeds your approval
table-imports/startNeeds your approval
table-imports/stepNeeds your approval
upload-runs/startNeeds your approval
verdicts/recordNeeds your approval
well-imports/previewNeeds your approval
well-imports/startNeeds your approval
well-imports/stepNeeds your approval
well-names/acceptNeeds your approval
publications/deriveRuns as part of a request you approved
upload-runs/convertRuns as part of a request you approved
upload-runs/convert-originalRuns as part of a request you approved
upload-runs/convert-outputRuns as part of a request you approved
upload-runs/fileRuns as part of a request you approved

Every operation in the deployment’s /api/v1/openapi.json carries its declaration as x-ophiolite-agent, and agents/declarations answers all of them at once.

Every result an agent creates records the agent, you as the person it acted for, and the approved request, on the run itself. Settings → Agents shows what each agent used today; the audit export (agents/audit) lists every execution with who approved it.

Each journey from the builder guides, step by step, with who does each step when an assistant does the journey for you. Your assistant does 31 of the 50 steps today; a step marked “Your assistant” is checked on every release by running the journey with an agent’s key, apart from the limits a step names.

The guide

StepWho does itWhat it touches
List the wells inside the person’s box, in CRS84.Your assistantReads
Read the extent of the wells the person can see.Your assistantReads
Write the wells as GeoJSON features for the person’s map.Your assistantFiles on your computer

The guide

StepWho does itWhat it touches
Find the shared log among the items the person can read.Your assistantReads
Read the GR curve at the listed revision.Your assistantReads
Put the curve in a table whose missing sample stays missing.Your assistantFiles on your computer

The guide

StepWho does itWhat it touches
Find the shared tops among the items the person can read.Your assistantReads
Read the tops at their revision.Your assistantReads
Read which well or wellbore the tops belong to.Your assistantReads
Write tops.csv with one row per top and the depths unchanged.Your assistantFiles on your computer

The guide

StepWho does itWhat it touches
Get the point set into the assistant’s folder, held at its revision.Your assistantReads
Fetch the trusted triangulation and run it on this computer, on the held point set.Your assistantReads
Propose sending the run and the surface it made.Your assistantA change you approve
The person approves sending exactly that run and surface.You approveOnly a person
Report the run and publish the surface it made, under the approved plan.Your assistantA change you approve
Read the surface’s history: its one version and how it was calculated.Your assistantReads

The guide

StepWho does itWhat it touches
Take the project’s state for the first time.Your assistantReads
Catch up with what changed since, including the newly shared log.Your assistantReads

The guide

StepWho does itWhat it touches
Find the selected well table among the sources.Your assistantReads
Read every row at the expected revision.Your assistantReads
Write the rows to a CSV file.Your assistantFiles on your computer

The guide

StepWho does itWhat it touches
Read the table’s columns and what the evidence says about each.Your assistantReads
Write the mapping of columns to well fields the evidence settles.Your assistantFiles on your computer
Propose the import as one job: preview, start bound to that preview, run, and preview again.Your assistantA change you approve
The person approves the exact job.You approveOnly a person
Preview what the import would create; the job waits at each row the evidence cannot settle.Your assistantA change you approve
The person answers each statement and column the evidence could not settle.You chooseOnly a person
Start the import bound to the settled preview.Your assistantA change you approve
Run the import’s steps to the end.Your assistantA change you approve
Preview again without a coordinate confirmation: nothing is asked and nothing is left to create.Your assistantA change you approve
List the imported wells and the kept copy they came from.Your assistantReads
Read the kept copy and join each well to its row.Your assistantReads

The guide

StepWho does itWhat it touches
Find the well and its present position.Not yet: this step is not yet checked with an assistantReads
Run the trusted correction on this computer, from the kept copy.Not yet: an assistant cannot send a result it computed yetFiles on your computer
Propose sending the run and the corrected position as version 1.Not yet: an assistant cannot send a result it computed yetA change you approve
The person approves the exact correction.Not yet: an assistant cannot send a result it computed yetOnly a person
Report the run under the approved plan.Not yet: an assistant cannot send a result it computed yetA change you approve
Publish version 1, the position the reported run made.Not yet: an assistant cannot send a result it computed yetPart of a request you approved
Read who may see the correction and who could be shown it.Not yet: this step is not yet checked with an assistantReads
Propose showing the correction to the colleagues.Not yet: this step is not yet checked with an assistantA change you approve
The person approves the exact share.Not yet: this step is not yet checked with an assistantOnly a person
Share the correction under the approved plan.Not yet: this step is not yet checked with an assistantA change you approve
Run the trusted correction again for a second position.Not yet: an assistant cannot send a result it computed yetFiles on your computer
Propose sending the second run as version 2 of the same item.Not yet: an assistant cannot send a result it computed yetA change you approve
The person approves the exact second correction.Not yet: an assistant cannot send a result it computed yetOnly a person
Report the second run under the approved plan.Not yet: an assistant cannot send a result it computed yetA change you approve
Publish version 2, the position the second run made.Not yet: an assistant cannot send a result it computed yetPart of a request you approved

The guide

StepWho does itWhat it touches
Give the member’s access an end date.Only you, because it changes who has accessOnly a person
Read the person’s own projects and when their access ends.Your assistantReads
Read who has access to the project, and until when.Your assistantReads
Technical reference

agent_wells_on_a_map (builder task builder_wells_on_a_map, run as the member):

StepOperationsActor
find-wellsentities/listagent, mcp
extententities/extentagent, mcp
write-geojsonnoneagent, none

agent_curves_into_python (builder task builder_curves_into_python, run as the member):

StepOperationsActor
find-curvescientific-assets/listagent, http
read-curvescientific-assets/describe, scientific-assets/representationagent, http
to-framenoneagent, none

agent_tops_for_another_application (builder task builder_tops_for_another_application, run as the member):

StepOperationsActor
find-topsscientific-assets/listagent, http
read-topsscientific-assets/describe, scientific-assets/representationagent, http
wells-of-topsentities/associationsagent, mcp
write-csvnoneagent, none

agent_surface_from_points (builder task builder_surface_from_points, run as the owner):

StepOperationsActor
read-pointscatalog/inventory, scientific-assets/describe, scientific-assets/representation, applications/result-historyagent, http
run-toolprocedures/get, procedures/bundleagent, http
propose-sendcapabilities/describe, agents/propose, agents/statusagent, http
approve-sendagents/approveapproval
sendcapabilities/describe, agents/status, procedure-runs/report, procedures/get, publications/derive, agents/proposeagent, http
historyapplications/result-historyagent, mcp

agent_keep_in_step (builder task builder_keep_in_step, run as the member):

StepOperationsActor
first-syncchanges/head, capabilities/describe, entities/list, catalog/inventory, result-groups/list, changes/listagent, mcp
catch-upchanges/head, capabilities/describe, changes/list, catalog/inventoryagent, mcp

agent_source_in_python (builder task builder_source_in_python, run as the administrator):

StepOperationsActor
find-sourcesources/listagent, mcp
read-sourcesources/export-fileagent, http
write-csvnoneagent, none

agent_wells_from_a_table (builder task builder_wells_from_a_table, run as the administrator):

StepOperationsActor
read-columnssources/schemaagent, mcp
write-mappingnoneagent, none
propose-importjobs/proposeagent, mcp
approve-importagents/approveapproval
previewjobs/stepagent, mcp
choose-columnsjobs/answerchoice
start-importjobs/stepagent, mcp
run-importjobs/stepagent, mcp
nothing-leftjobs/stepagent, mcp
list-wells-with-sourceentities/list, releases/list, releases/getagent, mcp
read-kept-copyreleases/download-snapshotagent, http

agent_well_position (builder task builder_well_position, run as the administrator):

StepOperationsActor
find-wellentities/listnot yet (agent; opens with E156), mcp
run-tool-version-1nonenot yet (agent; opens with E155), none
propose-send-version-1agents/proposenot yet (agent; opens with E155), mcp
approve-send-version-1agents/approvenot yet (approval; opens with E155)
send-run-version-1procedure-runs/reportnot yet (agent; opens with E155), mcp
send-result-version-1publications/derivenot yet (agent; opens with E155), http
find-colleaguesapplications/result-list, publications/infonot yet (agent; opens with E156), mcp
propose-shareagents/proposenot yet (agent; opens with E156), mcp
approve-shareagents/approvenot yet (approval; opens with E156)
sharepublications/sharenot yet (agent; opens with E156), mcp
run-tool-version-2nonenot yet (agent; opens with E155), none
propose-send-version-2agents/proposenot yet (agent; opens with E155), mcp
approve-send-version-2agents/approvenot yet (approval; opens with E155)
send-run-version-2procedure-runs/reportnot yet (agent; opens with E155), mcp
send-result-version-2publications/derivenot yet (agent; opens with E155), http

agent_running_a_project (builder task builder_running_a_project, run as the administrator):

StepOperationsActor
set-end-dateaccess/end-dateperson (access)
own-projectsprojects/listagent, mcp
who-has-accessaccess/effectiveagent, mcp

The record is conformance/journeys/journeys.json (ophiolite.agent-journeys/1); the agent conformance mode runs each journey whose steps are all decided.

If the agent loses the answer to a change (a crash, a network cut, you signed out), it asks for the recorded outcome by its command id and never repeats the work: running the same approved request again returns the recorded answer. An agent keeps working after you sign out of the browser; it stops when it expires, when you revoke it, or when you lose access to the project.

from ophiolite.agents import AgentClient
agent = AgentClient('https://ophiolite.example', 'my-project', credential)
setup = agent.run('applications/configure', {'name': 'Gamma correction', 'asset_id': asset,
'asset_revision': revision, 'curve': 'GR', 'runners': [me], 'command_id': 'cfg-1'})
run = agent.run('applications/start', {'id': setup['id'], 'generation': setup['generation'],
'command_id': 'run-1', 'application_version': 'my-script/1'})
result = agent.run('applications/publish', {'id': run['id'], 'changes': [{'index': 0, 'value': 2}]},
'Publish the corrected gamma ray') # waits until you approve
agent.recover(command_id='run-1') # after a lost answer

run() proposes, waits for your decision and executes; PlanDeclined, PlanExpired, BudgetExhausted and CommandOwned tell the agent why it cannot continue.

A job is one to eight steps that you approve once. A later step can use part of an earlier step’s answer: {"$step": 1, "pointer": "/id"} is the id of step 1’s answer.

from ophiolite.errors import ChoiceRequired
steps = [{'operation': 'applications/configure', 'body': {'name': 'Gamma correction', 'asset_id': asset,
'asset_revision': revision, 'curve': 'GR', 'runners': [me], 'command_id': 'cfg-1'}},
{'operation': 'applications/start', 'body': {'id': {'$step': 1, 'pointer': '/id'},
'generation': {'$step': 1, 'pointer': '/generation'}, 'command_id': 'run-1',
'application_version': 'my-script/1'}}]
try:
answers = agent.run_job(steps) # proposes, waits until you approve, runs each step in order
except ChoiceRequired as asked:
print(asked.question, asked.choices) # a step needs your decision
# ... you answer it ...
answers = agent.resume(asked.plan) # carries on from that step
  • You approve once. The job waits in Settings → Agents like any proposal. Your approval covers every step, in the order shown.
  • Which operations a job may run is decided by the server. An operation that only a person may do, or one that is not a job step, is refused when the agent proposes it. The SDK itself refuses a step that names another project, and a list that is not 1 to 8 {operation, body} steps, before anything is sent (Refused).
  • When a step needs your decision, the job stops at that step. The question and its choices appear on its card in Settings → Agents and Activity → Agents. The agent receives ChoiceRequired with the question, the choices, the plan and the step. After you choose, resume(plan) carries on from that step.
  • Recovery. Each step has a fixed command id, derived from the plan and the step number, so it is the same in every process. If the agent restarts, resume(plan) replays the completed steps by those ids, which returns their recorded answers and changes nothing, and then runs the rest. Running the same steps again is safe: the same steps are the same plan. If a step completed but its answer was never stored, CommandOwned is raised; the SDK cannot recover that answer.

From your own Python session you can list what waits for you and answer a question:

from ophiolite import Client
me = Client('https://ophiolite.example', 'my-project', my_credential) # yours, not the agent's key
for item in me.proposals(): # pending plans and jobs waiting for your choice
if item.get('question'):
me.answer(item['choice_token'], item['choices'][0]['id'])

Only the person the agent acts for can answer. An agent’s key is refused on both calls (agent-refused). A token that was already used, belongs to another job, is out of date or belongs to another person’s agent raises ChoiceRefused; details['reason'] says which (token-used, token-foreign, token-stale, not-the-delegator).

folder = agent.procedure_fetch(digest) # the checked local copy of that tool version
ex = agent.exchange('work') # holds the inputs the run reads
ex.send_run('runs/shifted', name='Shifted tops', of_entity=wellbore_id) # waits until you approve
  • procedure_fetch refuses early what a run of that version would be refused for: an import step, a withdrawn version and an unverified one (ToolRunRefused), and a version not enabled in the project yet (NotRun, code not-enabled). A version the agent cannot see answers as not found. Whether you trust the version is asked when the agent proposes the send.
  • of_entity names the well or wellbore a result is about: one id, or one per output ({'shifted': wellbore_id}). The agent reads it once and keeps it with the send. Your approval names it as you read it then (“about the wellbore …”); if it is no longer yours to read when the result is published, nothing is published.
  • The result’s history names the tool version that made each revision (made_with) and the revisions it was made from (parents). A parent you cannot read is left out, and parent_visibility reads restricted.

The service offers a remote MCP endpoint at https://<your service>/mcp (streamable HTTP). An MCP client connects with the agent’s key as a bearer header — nothing else: a browser cookie or page origin is refused. What the agent may call is exactly what it may do: read your data (curves up to 5,000 samples are returned exactly, with units, depth and missing values; larger data through the Python SDK), propose changes, and carry out the changes you or its settings approved. There is no call that approves, declines, registers or revokes: you decide in Workspace. Every call goes through the same checks as the rest of the service — plans, daily limits, ownership, your current permissions — and answers with the same error codes.

from ophiolite.agents import mcp_settings
mcp_settings('https://ophiolite.example', credential)
# {'url': 'https://ophiolite.example/mcp', 'transport': 'streamable-http',
# 'headers': {'Authorization': 'Bearer oph_agent_…'}}

agent.capabilities() (or the MCP call capabilities.describe) lists every operation with whether this agent may ask for it, whether it needs a plan, and its limits used today.

An assistant — a script or an MCP client — can also act through your own sign-in instead of a key. It signs in with the service’s application sign-in (the same one the Python SDK uses), then asks you: Workspace shows “Assistant: ” with what it may do, its daily limits (5 calculation runs, 1 publication) and a confirmation code. Once you approve, the assistant works under the same rules as an agent with a key — its reach, your scopes, a plan you approve for every change (assistants have no automatic approvals) — and appears in Settings → Agents, where you can revoke it; revoking the approval in Application access ends it as well. One sign-in holds one assistant; sign in again for another.

from ophiolite.auth import device_login
from ophiolite.agents import AgentClient
signed_in = device_login('https://ophiolite.example', 'my-project', write=True,
assistant='Notebook assistant', notify=print)
assistant = AgentClient('https://ophiolite.example', 'my-project', signed_in)

An MCP client that signs in this way sends only its bearer token to /mcp; before you approve it sees one call, access.request, which returns the Workspace address and code for you. The endpoint’s protected-resource metadata (/.well-known/oauth-protected-resource/mcp) names the identity provider; only its pre-registered application client is accepted.

MCP clients that register themselves with the identity provider (dynamic registration or client metadata documents), automatic approvals for assistants and linked sources; see Availability.