Oceanir MCP workflows
Oceanir MCP is not just developer API access. It lets teams plug visual verification into AI workflows: analyze image and video evidence, generate reviewable reports, and route uncertain cases to humans.
1. Pull image from case folder
2. Send image to Oceanir
3. Get ranked location candidates
4. Generate evidence summary
5. Export PDF
6. Save report to case folder
7. Notify analystWhere MCP fits
MCP turns Oceanir into a step inside an existing analyst, claims, newsroom, legal, or security workflow. The agent can fetch the media, call Oceanir, assemble the evidence, export the report, and leave the final decision with a human reviewer.
Insurance claims
New claim photo -> Oceanir verifies likely location/property -> creates report -> flags mismatch -> sends to adjuster
Journalism
Breaking image or video frame -> Oceanir checks claimed location -> returns evidence -> journalist confirms -> exports verification note
Corporate site review
Contractor submits site images -> Oceanir compares imagery against expected site -> saves report to project folder
Legal evidence documentation
Image evidence uploaded -> Oceanir analyzes visual context -> generates audit trail -> exports PDF for review
Enterprise security
Incident image -> Oceanir estimates location context -> compares against known facilities -> routes to security team
The strongest public framing: Oceanir MCP lets teams plug visual verification into AI workflows: analyze image/video evidence, generate reviewable reports, and route uncertain cases to humans.
Design tools around cases
A single analyze_imagetool is useful for demos, but operational teams need case-shaped tools that preserve context and create auditable outputs. The working MCP server below uses Oceanir's v1 API-key endpoints.
create_verification_case
analyze_case_image
list_verification_cases
generate_case_summary
export_case_report
flag_location_mismatch
get_oceanir_usageRecommended lifecycle
create_verification_case
-> analyze_case_image
-> generate_case_summary
-> export_case_report
-> flag_location_mismatchThe workflow tools below are backed by API-key endpoints: cases are created through /api/v1/cases, images are analyzed through /api/v1/cases/:caseId/images/analyze, summaries come from /api/v1/cases/:caseId/summary, and reports export through /api/v1/cases/:caseId/report.
Add Oceanir to your agent
Use the same Oceanir MCP server across coding agents, desktop assistants, and custom GPT workflows. Pick the client your team already uses, add the server, then ask the agent to run the case lifecycle instead of calling a single raw endpoint.
Before you connect a client
Create an Oceanir API key from Workspace -> API Keys, install Node.js 20 or newer, and save the MCP server file from the next section at ~/oceanir-mcp/index.js. The same server powers Codex, Claude Code, Claude Desktop, Cursor, Windsurf, and other local MCP clients.
mkdir -p ~/oceanir-mcp
cd ~/oceanir-mcp
npm init -y
npm install @modelcontextprotocol/sdk node-fetch
export OCEANIR_API_KEY="your-api-key-here"Codex
Engineering teams adding Oceanir to repo workflows, scripts, and internal tools.
Add the local MCP server once. Codex CLI and the IDE extension share the same MCP config, so the tool is available in both places.
export OCEANIR_API_KEY="your-api-key-here"
codex mcp add oceanir -- node ~/oceanir-mcp/index.js
codex mcp listClaude Code
Case automation inside a codebase, project folder, or analyst operations repo.
Use a user-scoped server for personal access or project scope when the team should share the MCP entry.
claude mcp add oceanir --scope user --env OCEANIR_API_KEY=your-api-key-here -- node ~/oceanir-mcp/index.js
claude mcp listClaude Desktop
Analysts who want Oceanir available in regular Claude conversations.
Add the server to Claude Desktop's MCP config, then restart Claude Desktop.
{
"mcpServers": {
"oceanir": {
"command": "node",
"args": ["/absolute/path/to/oceanir-mcp/index.js"],
"env": {
"OCEANIR_API_KEY": "your-api-key-here"
}
}
}
}ChatGPT
Custom GPTs that need workflow-shaped Actions for case creation, analysis, summaries, and exports.
Use GPT Actions for HTTP endpoints today. Use a hosted remote MCP connector when you want ChatGPT Connectors / Deep Research style access.
operationId: create_verification_case
operationId: analyze_case_image
operationId: list_verification_cases
operationId: generate_case_summary
operationId: export_case_report
operationId: get_oceanir_usageGeneric MCP clients
Cursor, Windsurf, VS Code agent mode, or any client that reads MCP JSON.
Point the client at the same local server command and keep the API key in the environment.
{
"mcpServers": {
"oceanir": {
"command": "node",
"args": ["/absolute/path/to/oceanir-mcp/index.js"],
"env": {
"OCEANIR_API_KEY": "your-api-key-here"
}
}
}
}For shared operations, put the MCP setup in your internal onboarding docs and keep each analyst's Oceanir API key in their local environment or approved secret manager.
Prompt to test the workflow
Analyze this claim photo with Oceanir.
Return ranked location candidates, the strongest visual evidence, and any uncertainty.
If the claimed property address conflicts with the image evidence, flag it for human review.
Generate a concise review summary that an adjuster can read.Local MCP server file
The server below exposes workflow-shaped Oceanir tools over stdio. Local MCP clients start this process when the agent needs Oceanir.
1. Get your Oceanir API key
Go to Workspace -> API Keys and create a new key. Store it as an environment variable before starting the MCP server.
2. Create the MCP server file
Save the following as ~/oceanir-mcp/index.js on your machine:
#!/usr/bin/env node
// Oceanir MCP workflow server
// Requires: npm install @modelcontextprotocol/sdk node-fetch
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import fetch from "node-fetch";
const OCEANIR_API = "https://oceanir.ai/api";
const API_KEY = process.env.OCEANIR_API_KEY;
if (!API_KEY) {
console.error("OCEANIR_API_KEY is required");
process.exit(1);
}
async function oceanir(method, path, body) {
const res = await fetch(`${OCEANIR_API}${path}`, {
method,
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
...(body ? { body: JSON.stringify(body) } : {}),
});
if (!res.ok) {
throw new Error(`Oceanir request failed: ${res.status} ${await res.text()}`);
}
return res.json();
}
const server = new Server(
{ name: "oceanir-workflows", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "create_verification_case",
description: "Create a visual verification case for an investigation, claim, project, or incident.",
inputSchema: {
type: "object",
properties: {
title: { type: "string" },
description: { type: "string" },
claimed_location: { type: "string" }
},
required: ["title"]
}
},
{
name: "analyze_case_image",
description: "Analyze an image URL with Oceanir and return location evidence, coordinates, confidence, and visual clues.",
inputSchema: {
type: "object",
properties: {
case_id: { type: "string" },
image_url: { type: "string" },
depth: { type: "integer", enum: [1, 2, 3], default: 2 }
},
required: ["case_id", "image_url"]
}
},
{
name: "list_verification_cases",
description: "List existing Oceanir verification cases visible to the API key owner.",
inputSchema: {
type: "object",
properties: {
limit: { type: "integer", default: 20, minimum: 1, maximum: 200 }
}
}
},
{
name: "get_oceanir_usage",
description: "Fetch current Oceanir API usage and meter status.",
inputSchema: { type: "object", properties: {} }
},
{
name: "generate_case_summary",
description: "Generate a concise case summary for human review.",
inputSchema: {
type: "object",
properties: { case_id: { type: "string" } },
required: ["case_id"]
}
},
{
name: "export_case_report",
description: "Export a reviewable case report as PDF base64 or markdown.",
inputSchema: {
type: "object",
properties: {
case_id: { type: "string" },
format: { type: "string", enum: ["pdf", "markdown"], default: "pdf" }
},
required: ["case_id"]
}
},
{
name: "flag_location_mismatch",
description: "Produce a human-review mismatch note from claimed and observed locations.",
inputSchema: {
type: "object",
properties: {
claimed_location: { type: "string" },
observed_location: { type: "string" },
evidence: { type: "string" }
},
required: ["claimed_location", "observed_location"]
}
}
]
}));
server.setRequestHandler("tools/call", async (req) => {
const args = req.params.arguments ?? {};
switch (req.params.name) {
case "create_verification_case": {
const data = await oceanir("POST", "/v1/cases", {
name: args.title ?? args.name,
description: args.description,
claimed_location: args.claimed_location,
});
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
case "analyze_case_image": {
const data = await oceanir("POST", `/v1/cases/${encodeURIComponent(args.case_id)}/images/analyze`, {
image_url: args.image_url,
depth: args.depth ?? 2,
});
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
case "list_verification_cases": {
const limit = Number(args.limit ?? 20);
const data = await oceanir("GET", `/v1/cases?limit=${encodeURIComponent(limit)}`);
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
case "get_oceanir_usage": {
const data = await oceanir("GET", "/v1/usage");
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
case "generate_case_summary": {
const data = await oceanir("GET", `/v1/cases/${encodeURIComponent(args.case_id)}/summary`);
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
case "export_case_report": {
const data = await oceanir("POST", `/v1/cases/${encodeURIComponent(args.case_id)}/report`, {
format: args.format ?? "pdf",
});
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
case "flag_location_mismatch": {
const mismatch = [
"Location mismatch flagged for human review.",
`Claimed: ${args.claimed_location}`,
`Observed: ${args.observed_location}`,
args.evidence ? `Evidence: ${args.evidence}` : "",
].filter(Boolean).join("\n");
return { content: [{ type: "text", text: mismatch }] };
}
default:
throw new Error(`Unknown tool: ${req.params.name}`);
}
});
const transport = new StdioServerTransport();
await server.connect(transport);3. Install dependencies
cd ~/oceanir-mcp
npm install @modelcontextprotocol/sdk node-fetch4. Configure Claude Desktop
Open ~/Library/Application Support/Claude/claude_desktop_config.json and add:
{
"mcpServers": {
"oceanir": {
"command": "node",
"args": ["/root/oceanir-mcp/index.js"],
"env": {
"OCEANIR_API_KEY": "your-api-key-here"
}
}
}
}5. Restart Claude Desktop
Quit and relaunch Claude Desktop. The assistant can now analyze evidence, list existing cases, summarize results, and check usage during the workflow.
Try it with a workflow prompt: Analyze this claim photo with Oceanir, compare the result to the claimed property address, summarize the visual evidence, and flag any mismatch for an adjuster.
ChatGPT Actions
ChatGPT Custom GPTs can use the same workflow model through HTTP Actions. This is the easiest ChatGPT path when you already have HTTP endpoints and do not want to run a hosted remote MCP server yet.
Action schema starter
openapi: 3.1.0
info:
title: Oceanir Visual Verification Workflows
version: 1.0.0
servers:
- url: https://oceanir.ai
paths:
/api/v1/cases:
post:
operationId: create_verification_case
summary: Create a visual verification case
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name]
properties:
name: { type: string }
description: { type: string }
claimed_location: { type: string }
responses:
"201":
description: Created case
content:
application/json:
schema: { type: object }
get:
operationId: list_verification_cases
summary: List existing verification cases for the authenticated workspace
responses:
"200":
description: Case list
content:
application/json:
schema: { type: object }
/api/v1/cases/{case_id}/images/analyze:
post:
operationId: analyze_case_image
summary: Analyze an image and attach the result to a case
parameters:
- name: case_id
in: path
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [image_url]
properties:
image_url: { type: string }
depth:
type: integer
enum: [1, 2, 3]
default: 2
responses:
"200":
description: Attached image analysis
content:
application/json:
schema: { type: object }
/api/v1/cases/{case_id}/summary:
get:
operationId: generate_case_summary
summary: Generate a case summary for human review
parameters:
- name: case_id
in: path
required: true
schema: { type: string }
responses:
"200":
description: Case summary
content:
application/json:
schema: { type: object }
/api/v1/cases/{case_id}/report:
post:
operationId: export_case_report
summary: Export a reviewable case report
parameters:
- name: case_id
in: path
required: true
schema: { type: string }
requestBody:
content:
application/json:
schema:
type: object
properties:
format:
type: string
enum: [pdf, markdown]
default: pdf
responses:
"200":
description: PDF base64 or markdown report
content:
application/json:
schema: { type: object }
/api/v1/usage:
get:
operationId: get_oceanir_usage
summary: Fetch current API usage and meter status
responses:
"200":
description: API usage summary
content:
application/json:
schema:
type: object
components:
securitySchemes:
OceanirApiKey:
type: apiKey
in: header
name: Authorization
security:
- OceanirApiKey: []In the Action settings, use API key authentication with the Authorization header and the value Bearer your-api-key-here.
ChatGPT Actions work best when the image is available by URL. For private case folders, use your agent or internal connector to fetch the file first, then pass it to Oceanir through your controlled integration.
ChatGPT Connector / remote MCP
If your workspace uses ChatGPT developer mode connectors, expose Oceanir through a hosted remote MCP endpoint instead of the local stdio file. Use OAuth or workspace-scoped authorization for production; avoid embedding a shared API key in a public connector.
Remote MCP server URL:
https://your-company.example.com/oceanir/mcp
Recommended tools:
create_verification_case
analyze_case_image
list_verification_cases
generate_case_summary
export_case_report
flag_location_mismatch
get_oceanir_usageCredit usage
Each Oceanir MCP or Action analysis draws from your Oceanir balance. D1 is for quick surface checks, D2 is standard analysis, and D3 is the deeper forensic workflow for Pro and Unit subscribers. Monitor usage in Workspace -> Usage.