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.
Add an agent
Section titled “Add an agent”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.
Approve what it proposes
Section titled “Approve what it proposes”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.
What an agent may do
Section titled “What an agent may do”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 do | How |
|---|---|
| Configure application | Needs your approval |
| Publish application | Needs your approval |
| Share application | Needs your approval |
| Start application | Needs your approval |
| Keep your saved mapping of a table of this project’s connection as a project layout | Needs your approval |
| Keep a reviewed mapping as a layout, or a new version of one | Needs your approval |
| Ask for a database to be added, without a sign-in | Needs your approval |
| Withdraw your own request | Needs your approval |
| Deliver as an outcome | Needs your approval |
| Report a run of an enabled procedure version | Needs your approval |
| Register a procedure bundle | Needs your approval |
| Record that you trust the code of one procedure version in this project | Needs your approval |
| Set who may read and reuse your derived publication, within its roots’ ceiling | Needs your approval |
| Make an exact result version again | Needs your approval |
| Cancel a queued or running job | Needs your approval |
| Queue a script to complete one of your recorded runs in the sandboxed runner | Needs your approval |
| Bind upstream source | Needs your approval |
| Mapping-save upstream source | Needs your approval |
| Say what an import of the input would do with a target and a mapping | Needs your approval |
| Read a table file for an import | Needs your approval |
| Start the reviewed import | Needs your approval |
| Run the next rows as the person who started the import | Needs your approval |
| Start a folder upload | Needs your approval |
| Record that you accept or reject one exact result version, with your reason | Needs your approval |
| Read a table of wells and say which rows become wells, which are already here and which are skipped, with reasons | Needs your approval |
| Start the reviewed import | Needs your approval |
| Run the next rows as the person who started the import, each in its own transaction | Needs 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 step | Needs your approval |
| Publish a file derived from exact revisions you may reuse, with its declared method | Runs 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 computer | Runs as part of a request you approved |
| The original of a conversion declared with keep_original | Runs as part of a request you approved |
| One file a read procedure made | Runs as part of a request you approved |
| One file of a folder upload | Runs as part of a request you approved |
Technical reference
| Operation | How |
|---|---|
applications/configure | Needs your approval |
applications/publish | Needs your approval |
applications/share | Needs your approval |
applications/start | Needs your approval |
layouts/keep | Needs your approval |
layouts/save | Needs your approval |
org-connections/request | Needs your approval |
org-connections/request-withdraw | Needs your approval |
outcomes/deliver-as | Needs your approval |
procedure-runs/report | Needs your approval |
procedures/register | Needs your approval |
procedures/trust | Needs your approval |
publications/share | Needs your approval |
results/remake-run | Needs your approval |
runners/cancel | Needs your approval |
runners/submit | Needs your approval |
sources/bind | Needs your approval |
sources/mapping-save | Needs your approval |
table-imports/preview | Needs your approval |
table-imports/read | Needs your approval |
table-imports/start | Needs your approval |
table-imports/step | Needs your approval |
upload-runs/start | Needs your approval |
verdicts/record | Needs your approval |
well-imports/preview | Needs your approval |
well-imports/start | Needs your approval |
well-imports/step | Needs your approval |
well-names/accept | Needs your approval |
publications/derive | Runs as part of a request you approved |
upload-runs/convert | Runs as part of a request you approved |
upload-runs/convert-original | Runs as part of a request you approved |
upload-runs/convert-output | Runs as part of a request you approved |
upload-runs/file | Runs 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.
Journeys an assistant runs
Section titled “Journeys an assistant runs”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.
Wells on a map
Section titled “Wells on a map”| Step | Who does it | What it touches |
|---|---|---|
| List the wells inside the person’s box, in CRS84. | Your assistant | Reads |
| Read the extent of the wells the person can see. | Your assistant | Reads |
| Write the wells as GeoJSON features for the person’s map. | Your assistant | Files on your computer |
Read curves in Python
Section titled “Read curves in Python”| Step | Who does it | What it touches |
|---|---|---|
| Find the shared log among the items the person can read. | Your assistant | Reads |
| Read the GR curve at the listed revision. | Your assistant | Reads |
| Put the curve in a table whose missing sample stays missing. | Your assistant | Files on your computer |
Formation tops in another application
Section titled “Formation tops in another application”| Step | Who does it | What it touches |
|---|---|---|
| Find the shared tops among the items the person can read. | Your assistant | Reads |
| Read the tops at their revision. | Your assistant | Reads |
| Read which well or wellbore the tops belong to. | Your assistant | Reads |
| Write tops.csv with one row per top and the depths unchanged. | Your assistant | Files on your computer |
Publish a result you computed in Python
Section titled “Publish a result you computed in Python”| Step | Who does it | What it touches |
|---|---|---|
| Get the point set into the assistant’s folder, held at its revision. | Your assistant | Reads |
| Fetch the trusted triangulation and run it on this computer, on the held point set. | Your assistant | Reads |
| Propose sending the run and the surface it made. | Your assistant | A change you approve |
| The person approves sending exactly that run and surface. | You approve | Only a person |
| Report the run and publish the surface it made, under the approved plan. | Your assistant | A change you approve |
| Read the surface’s history: its one version and how it was calculated. | Your assistant | Reads |
Keep in step with Workspace
Section titled “Keep in step with Workspace”| Step | Who does it | What it touches |
|---|---|---|
| Take the project’s state for the first time. | Your assistant | Reads |
| Catch up with what changed since, including the newly shared log. | Your assistant | Reads |
Read a connected source in Python
Section titled “Read a connected source in Python”| Step | Who does it | What it touches |
|---|---|---|
| Find the selected well table among the sources. | Your assistant | Reads |
| Read every row at the expected revision. | Your assistant | Reads |
| Write the rows to a CSV file. | Your assistant | Files on your computer |
Import wells from a table
Section titled “Import wells from a table”| Step | Who does it | What it touches |
|---|---|---|
| Read the table’s columns and what the evidence says about each. | Your assistant | Reads |
| Write the mapping of columns to well fields the evidence settles. | Your assistant | Files on your computer |
| Propose the import as one job: preview, start bound to that preview, run, and preview again. | Your assistant | A change you approve |
| The person approves the exact job. | You approve | Only a person |
| Preview what the import would create; the job waits at each row the evidence cannot settle. | Your assistant | A change you approve |
| The person answers each statement and column the evidence could not settle. | You choose | Only a person |
| Start the import bound to the settled preview. | Your assistant | A change you approve |
| Run the import’s steps to the end. | Your assistant | A change you approve |
| Preview again without a coordinate confirmation: nothing is asked and nothing is left to create. | Your assistant | A change you approve |
| List the imported wells and the kept copy they came from. | Your assistant | Reads |
| Read the kept copy and join each well to its row. | Your assistant | Reads |
Correct a well’s position
Section titled “Correct a well’s position”| Step | Who does it | What it touches |
|---|---|---|
| Find the well and its present position. | Not yet: this step is not yet checked with an assistant | Reads |
| Run the trusted correction on this computer, from the kept copy. | Not yet: an assistant cannot send a result it computed yet | Files on your computer |
| Propose sending the run and the corrected position as version 1. | Not yet: an assistant cannot send a result it computed yet | A change you approve |
| The person approves the exact correction. | Not yet: an assistant cannot send a result it computed yet | Only a person |
| Report the run under the approved plan. | Not yet: an assistant cannot send a result it computed yet | A change you approve |
| Publish version 1, the position the reported run made. | Not yet: an assistant cannot send a result it computed yet | Part 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 assistant | Reads |
| Propose showing the correction to the colleagues. | Not yet: this step is not yet checked with an assistant | A change you approve |
| The person approves the exact share. | Not yet: this step is not yet checked with an assistant | Only a person |
| Share the correction under the approved plan. | Not yet: this step is not yet checked with an assistant | A change you approve |
| Run the trusted correction again for a second position. | Not yet: an assistant cannot send a result it computed yet | Files 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 yet | A change you approve |
| The person approves the exact second correction. | Not yet: an assistant cannot send a result it computed yet | Only a person |
| Report the second run under the approved plan. | Not yet: an assistant cannot send a result it computed yet | A change you approve |
| Publish version 2, the position the second run made. | Not yet: an assistant cannot send a result it computed yet | Part of a request you approved |
Running a project
Section titled “Running a project”| Step | Who does it | What it touches |
|---|---|---|
| Give the member’s access an end date. | Only you, because it changes who has access | Only a person |
| Read the person’s own projects and when their access ends. | Your assistant | Reads |
| Read who has access to the project, and until when. | Your assistant | Reads |
Technical reference
agent_wells_on_a_map (builder task builder_wells_on_a_map, run as the member):
| Step | Operations | Actor |
|---|---|---|
find-wells | entities/list | agent, mcp |
extent | entities/extent | agent, mcp |
write-geojson | none | agent, none |
agent_curves_into_python (builder task builder_curves_into_python, run as the member):
| Step | Operations | Actor |
|---|---|---|
find-curve | scientific-assets/list | agent, http |
read-curve | scientific-assets/describe, scientific-assets/representation | agent, http |
to-frame | none | agent, none |
agent_tops_for_another_application (builder task builder_tops_for_another_application, run as the member):
| Step | Operations | Actor |
|---|---|---|
find-tops | scientific-assets/list | agent, http |
read-tops | scientific-assets/describe, scientific-assets/representation | agent, http |
wells-of-tops | entities/associations | agent, mcp |
write-csv | none | agent, none |
agent_surface_from_points (builder task builder_surface_from_points, run as the owner):
| Step | Operations | Actor |
|---|---|---|
read-points | catalog/inventory, scientific-assets/describe, scientific-assets/representation, applications/result-history | agent, http |
run-tool | procedures/get, procedures/bundle | agent, http |
propose-send | capabilities/describe, agents/propose, agents/status | agent, http |
approve-send | agents/approve | approval |
send | capabilities/describe, agents/status, procedure-runs/report, procedures/get, publications/derive, agents/propose | agent, http |
history | applications/result-history | agent, mcp |
agent_keep_in_step (builder task builder_keep_in_step, run as the member):
| Step | Operations | Actor |
|---|---|---|
first-sync | changes/head, capabilities/describe, entities/list, catalog/inventory, result-groups/list, changes/list | agent, mcp |
catch-up | changes/head, capabilities/describe, changes/list, catalog/inventory | agent, mcp |
agent_source_in_python (builder task builder_source_in_python, run as the administrator):
| Step | Operations | Actor |
|---|---|---|
find-source | sources/list | agent, mcp |
read-source | sources/export-file | agent, http |
write-csv | none | agent, none |
agent_wells_from_a_table (builder task builder_wells_from_a_table, run as the administrator):
| Step | Operations | Actor |
|---|---|---|
read-columns | sources/schema | agent, mcp |
write-mapping | none | agent, none |
propose-import | jobs/propose | agent, mcp |
approve-import | agents/approve | approval |
preview | jobs/step | agent, mcp |
choose-columns | jobs/answer | choice |
start-import | jobs/step | agent, mcp |
run-import | jobs/step | agent, mcp |
nothing-left | jobs/step | agent, mcp |
list-wells-with-source | entities/list, releases/list, releases/get | agent, mcp |
read-kept-copy | releases/download-snapshot | agent, http |
agent_well_position (builder task builder_well_position, run as the administrator):
| Step | Operations | Actor |
|---|---|---|
find-well | entities/list | not yet (agent; opens with E156), mcp |
run-tool-version-1 | none | not yet (agent; opens with E155), none |
propose-send-version-1 | agents/propose | not yet (agent; opens with E155), mcp |
approve-send-version-1 | agents/approve | not yet (approval; opens with E155) |
send-run-version-1 | procedure-runs/report | not yet (agent; opens with E155), mcp |
send-result-version-1 | publications/derive | not yet (agent; opens with E155), http |
find-colleagues | applications/result-list, publications/info | not yet (agent; opens with E156), mcp |
propose-share | agents/propose | not yet (agent; opens with E156), mcp |
approve-share | agents/approve | not yet (approval; opens with E156) |
share | publications/share | not yet (agent; opens with E156), mcp |
run-tool-version-2 | none | not yet (agent; opens with E155), none |
propose-send-version-2 | agents/propose | not yet (agent; opens with E155), mcp |
approve-send-version-2 | agents/approve | not yet (approval; opens with E155) |
send-run-version-2 | procedure-runs/report | not yet (agent; opens with E155), mcp |
send-result-version-2 | publications/derive | not yet (agent; opens with E155), http |
agent_running_a_project (builder task builder_running_a_project, run as the administrator):
| Step | Operations | Actor |
|---|---|---|
set-end-date | access/end-date | person (access) |
own-projects | projects/list | agent, mcp |
who-has-access | access/effective | agent, mcp |
The record is conformance/journeys/journeys.json (ophiolite.agent-journeys/1); the agent conformance mode runs each journey whose steps are all decided.
Lost answers and repeats
Section titled “Lost answers and repeats”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 Python
Section titled “From Python”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 approveagent.recover(command_id='run-1') # after a lost answerrun() proposes, waits for your decision and executes; PlanDeclined, PlanExpired,
BudgetExhausted and CommandOwned tell the agent why it cannot continue.
Several steps under one approval
Section titled “Several steps under one approval”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 orderexcept 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
ChoiceRequiredwith the question, the choices, theplanand thestep. 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,CommandOwnedis 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 keyfor 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).
Fetch a tool and send what it made
Section titled “Fetch a tool and send what it made”folder = agent.procedure_fetch(digest) # the checked local copy of that tool versionex = agent.exchange('work') # holds the inputs the run readsex.send_run('runs/shifted', name='Shifted tops', of_entity=wellbore_id) # waits until you approveprocedure_fetchrefuses 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, codenot-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_entitynames 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, andparent_visibilityreadsrestricted.
Connect an AI assistant (MCP)
Section titled “Connect an AI assistant (MCP)”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.
Assistants that sign in as you
Section titled “Assistants that sign in as you”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:
from ophiolite.auth import device_loginfrom 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.
Not yet available
Section titled “Not yet available”MCP clients that register themselves with the identity provider (dynamic registration or client metadata documents), automatic approvals for assistants and linked sources; see Availability.
