oci-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@oci-mcplist all compute instances in the lab compartment"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
oci-mcp
An MCP server for operating Oracle Cloud Infrastructure from an MCP-aware agent — Identity, Compute, Block Volume, Networking (VCN), Object Storage and OKE.
Runs locally over stdio and reads credentials straight from ~/.oci/config,
so they never leave your machine.
Status: Phase 1. Read-only — orientation, list, get and search across 39 resource types. Write and delete phases are still to come — see Roadmap.
Requirements
Python 3.12 (pinned in
.python-version— theociSDK does not support 3.14)A working
~/.oci/config, verifiable withoci iam region-list
Related MCP server: mcp-server-oci
Install
uv syncRun
uv run oci-mcpIt speaks MCP over stdio, so on its own it just waits on stdin — that is correct behaviour, not a hang. Normally a client launches it; see Register with Claude Code.
Test
Unit tests — offline, no credentials, no network:
uv run pytest -qInspect the catalog without writing any client code:
uv run fastmcp list --command "uv run oci-mcp"
uv run fastmcp list --command "uv run oci-mcp" --output-schemaCall a tool directly, which is the fastest way to check a change end to end:
uv run fastmcp call --command "uv run oci-mcp" --target oci_whoami --jsonPass tool arguments with --input-json '{...}'. (Bare key=value pairs only
work when you give a server file instead of --command, which this package
cannot do — see the note below.)
Note: point
fastmcpat the--command, not atsrc/oci_mcp/server.py. Passing the file loads it as a standalone script rather than a package module, which breaks its relative imports.
Check the safety gates by varying the environment — the fail-closed default means an unconfigured server can mutate nothing:
# default: writes enabled but no allowlist -> mutations_possible false
uv run fastmcp call --command "uv run oci-mcp" --target oci_whoami --json
# allowlist set -> mutations_possible true, mutable_compartments [lab]
uv run fastmcp call --command "env OCI_MCP_COMPARTMENTS=lab uv run oci-mcp" \
--target oci_whoami --jsonThe env prefix is load-bearing: --command is executed without a shell, so a
bare VAR=value prefix would be treated as the program name and fail with
No such file or directory.
Verify the client sees it:
claude mcp list # expect: oci: ... - ✔ ConnectedConfigure
All settings are environment variables; see .env.example. The defaults fail closed — writes are enabled but the compartment allowlist is empty, so no mutating call can succeed until you name a compartment.
Variable | Default | Purpose |
|
| Profile in |
| profile's region | Region override |
|
| Register write tools |
|
| Register delete tools |
| (empty) | Compartments where mutation is permitted. Empty = none. |
|
| Mutation audit trail |
Register with Claude Code
A stdio server does not inherit your shell environment — the client supplies it.
So pass any non-default settings with --env, or they are silently ignored:
claude mcp add oci \
--env OCI_MCP_COMPARTMENTS=lab \
-- uv --directory "$PWD" run oci-mcpVerify by asking the agent to call oci_whoami; its permissions.notes will say
plainly why a mutation would be refused.
Safety model
Four independent layers, none of which rely on client cooperation:
Capability flags enforced at registration — a disabled capability's tools are absent from the catalog, not merely refusing when called.
Compartment allowlist — every mutating call resolves its target's compartment and is rejected outside the list.
Two-phase confirm tokens — destructive tools first return a preview plus a short-lived HMAC token bound to that exact operation and OCID; nothing is destroyed until the token is echoed back.
Append-only audit log of every mutation.
Tools
Tool | Notes |
| Active tenancy, user, region, auth method, and this server's own permissions |
| List one resource type. Omit |
| Full detail for one resource by OCID (buckets: by name) |
| Tenancy-wide Resource Search — structured query or free text |
Reads collapse into three dispatch tools because their schemas are uniform: "show me type in compartment". Writes will stay explicit because theirs are not.
Resource types
Service |
|
compute |
|
block_storage |
|
network |
|
oke |
|
database |
|
object_storage |
|
identity |
|
Every list is projected to the handful of fields that identify and locate a
resource; pass verbose=true for the full object. An OCI Instance has 36
fields, so this is the difference between a usable answer and a blown context.
Things worth knowing:
OKE clusters are not indexed by Resource Search.
oci_searchwill never return one; useoci_list('cluster').Buckets are addressed by name, not OCID:
oci_get('bucket', 'my-bucket').boot_volume_attachmentis availability-domain scoped; the server fans out across ADs for you.Nothing in the
databasegroup has been exercised against real resources — this tenancy has none — but every call is verified to return an empty list rather than an error.
Examples
C="uv run oci-mcp"
# every running instance in the tenancy
uv run fastmcp call --command "$C" --target oci_list \
--input-json '{"resource_type":"instance","lifecycle_state":"RUNNING"}' --json
# OKE clusters in one compartment
uv run fastmcp call --command "$C" --target oci_list \
--input-json '{"resource_type":"cluster","compartment":"test-deploy-kubeflow"}' --json
# one bucket, by name
uv run fastmcp call --command "$C" --target oci_get \
--input-json '{"resource_type":"bucket","target":"terraform-state-kubeflow"}' --json
# anything, anywhere, by structured query
uv run fastmcp call --command "$C" --target oci_search \
--input-json '{"query":"query all resources where lifecycleState = '"'"'RUNNING'"'"'"}' --jsonArguments must go through --input-json here: with --command in play, a bare
key=value positional is parsed as a server spec and fails with
Cannot use both a server spec and --command.
Roadmap
Phase | Scope |
0 ✅ | Scaffold, config, lazy clients, |
1 ✅ | Read layer — |
2 | Safety — compartment allowlist guard and audit log, landed before any write exists |
3 | Create and modify — explicit tools for instances, volumes, VCNs/subnets, buckets, OKE node pools |
Scope is deliberately list, create, modify. Delete/terminate is not planned;
the OCI_MCP_ALLOW_DELETE flag exists so it can be added later without
touching the architecture, but it stays false and registers nothing today.
Reads collapse into three dispatch tools since their schemas are uniform, while writes stay explicit because theirs are not.
License
Available Tools
4 toolsoci_getGet one OCI resourceARead-onlyIdempotent
Fetch full details for a single resource.
Use this after oci_list or oci_search has given you an OCID and you need the complete record — configuration, nested settings, tags.
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | The resource OCID. For resource_type='bucket' pass the bucket NAME instead. | |
| verbose | No | Full detail (default). Set false for the compact projection. | |
| resource_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds real value by telling the agent what it gets back ('configuration, nested settings, tags'), which is behavioral rather than restating annotations. It says nothing about auth requirements or rate limits, but with annotations and an output schema present those are less critical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, zero filler, with the core action front-loaded and the workflow cue immediately after. Every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, full annotation coverage, and a self-documenting enum of 38 resource types, the description only needs to establish the read-one workflow, which it does. It does not explain the breadth of resource_type choices, but the enum carries that load.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67%, above the baseline threshold, and the schema documents the bucket-NAME exception and the verbose toggle. The description reinforces that 'target' is an OCID obtained from oci_list/oci_search, but adds no format or validation detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch full details for a single resource') and the phrase 'single resource' implicitly contrasts with the list/search siblings. It stops short of naming an alternative directly in the purpose statement, so sibling separation is left partly to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent when to reach for this tool: 'after oci_list or oci_search has given you an OCID'. That is a concrete triggering condition referencing two named siblings. It lacks an explicit when-not clause, but the workflow context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oci_listList OCI resourcesARead-onlyIdempotent
List resources of one type, compactly.
Covers compute, block storage, networking, OKE, database, object storage and identity. Results are projected to the identifying fields; pass verbose=True for the full objects.
Omitting compartment scans the whole tenancy and tags each row with the
compartment it came from.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum rows to return. | |
| verbose | No | Return every field instead of the compact projection. | |
| compartment | No | Compartment name or OCID. Omit to scan every compartment in the tenancy. | |
| resource_type | Yes | ||
| lifecycle_state | No | Filter by state, e.g. RUNNING, AVAILABLE, ACTIVE, TERMINATED. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and open-world, so safety is covered. The description adds genuinely non-annotated behavior: results are projected to identifying fields by default, and a tenancy-wide scan when compartment is omitted tags each row with its origin. Return-shape detail is left to the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded paragraphs with no filler; the primary purpose leads and secondary behaviors follow. Efficient and readable, though slightly more verbose than a single tight paragraph would need to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the description covers scope, projection behavior and the omitted-compartment case. It leaves the list-vs-search boundary unstated, which is the main remaining gap for a tool with three siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (80%), so the schema already documents limit, verbose, compartment and resource_type. The description largely restates the verbose and compartment semantics that the schema already provides, adding no syntax or format detail beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (OCI resources of a single type), and enumerates the service families covered. It does not explicitly differentiate itself from siblings like oci_search or oci_get, so the agent must infer the boundary, but the core purpose is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives conditional guidance for two parameters (pass verbose=True for full objects; omit `compartment` to scan the whole tenancy), which is useful in-context usage. However, it never states when to reach for oci_list versus oci_search or oci_get, leaving the sibling routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oci_searchSearch OCI resourcesARead-onlyIdempotent
Find resources of any type across the whole tenancy in one call.
The fastest way to locate something when you do not know its compartment. Prefer this over sweeping oci_list across many types.
Examples: query="query all resources where lifecycleState = 'RUNNING'" query="query instance, volume resources where displayName =~ 'test'" free_text="kubeflow"
Note: Resource Search does not index every service. OKE clusters never appear; use oci_list('cluster') for those.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum rows to return. | |
| query | No | Structured query, e.g. "query instance resources where lifecycleState = 'RUNNING'". Use 'all' in place of a type to search every resource type. | |
| free_text | No | Plain-text search over names and tags. Mutually exclusive with query. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds non-obvious behavioral context the annotations cannot convey: that Resource Search does not index every service and that OKE clusters are never returned. Pagination/limit behavior is left to the schema, so not a full 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose statement, then the routing preference, then concrete examples, then a caveat. Every sentence carries distinct information and the example block is clearly delineated; nothing is redundant with the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, open-world search tool with an output schema, the description covers all decision-relevant information: scope, alternative tools, query syntax, and known coverage gaps. Return-value shape is handled by the output schema, so nothing an agent needs before calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the schema already documents each parameter. The description adds value on top by supplying a multi-type query example and the regex operator form (displayName =~ 'test'), plus a free_text example, which goes beyond the single example in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Find resources of any type across the whole tenancy") with explicit scope wording ("any type", "whole tenancy"). It also implicitly distinguishes itself from siblings by naming oci_list as the tool it replaces, so an agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit selection condition ("when you do not know its compartment"), a stated preference over the alternative ("Prefer this over sweeping oci_list across many types"), and a named exception with the correct fallback (OKE clusters never appear; use oci_list('cluster')). This is close to a complete routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
oci_whoamiWho am I on OCIARead-onlyIdempotent
Report the active OCI identity and this server's own permissions.
Returns the tenancy, user, region and auth method in use, plus which compartments may be mutated and which capability flags are enabled.
Call this first in a session to learn what is reachable before acting.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description goes beyond them by disclosing what is actually exposed (tenancy, user, region, auth method, which compartments may be mutated, capability flags) — security-relevant context about what the call reveals. Minor gap: no note on latency, caching, or whether identity can change mid-session.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each load-bearing: what it reports, exactly what comes back, and when to call it. Front-loaded with the verb and outcome; no filler or restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be spelled out, yet the description still summarizes them usefully. Combined with annotations covering the read-only/idempotent profile and a zero-parameter schema, an agent has everything required to invoke this correctly as a session-opening call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4. Nothing in the description is needed to clarify arguments, and nothing is misleading about input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Report') plus a precisely scoped resource: the active OCI identity and the server's own permissions. It further enumerates the exact fields returned (tenancy, user, region, auth method), which no sibling tool (oci_list/oci_get/oci_search) does, so an agent can distinguish it immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit sequencing rule: 'Call this first in a session to learn what is reachable before acting.' That is clear, actionable when-to-use guidance. It does not explicitly name the sibling tools or state when not to use it, but the intent is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
oci_get - First observed
oci_list - First observed
oci_search - First observed
oci_whoami
TDQS
Scored across 4 tools
oci_whoami, oci_list, oci_get, and oci_search have largely distinct purposes. The main overlap is between list (one resource type) and search (cross-type query), but descriptions clearly guide when to use each.
All four tools follow a consistent oci_<verb> snake_case pattern (oci_whoami, oci_list, oci_get, oci_search). The convention is predictable and readable.
Four tools is lean but appropriate for a focused read/discovery server, with each tool covering a distinct aspect: identity, enumeration, detail retrieval, and cross-type search. It is slightly thin for the broad OCI domain but not problematic.
The toolset is entirely read-only: no create, update, delete, or action tools exist, despite oci_whoami advertising mutation permissions. Agents tasked with modifying OCI resources will hit dead ends, constituting a significant gap for an OCI management server.
Maintenance
Related MCP Connectors
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
CloudOracle - 14-tool multi-cloud compliance MCP: AWS, Azure, GCP posture, IAM, configs.
- ZopDev MCPOAuthdev.zop
Cloud cost, inventory and governance on AWS/Azure/GCP. Read-only by default, optional scoped writes
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for Oracle Container Engine for Kubernetes (OKE) that enables inspection, querying, and troubleshooting of OKE clusters through safe, composable tools.Universal Permissive v1.0
- FlicenseNot gradedqualityBmaintenanceEnables interaction with Oracle Cloud Infrastructure through the MCP protocol. Supports dynamic profile selection and provides 85 tools for managing compute, databases, networking, IAM, storage, load balancers, OKE, monitoring, and cost management.-
- AlicenseAqualityDmaintenanceMCP server for Oracle Cloud Infrastructure (OCI) that provides tools to manage Compute, Object Storage, Block Storage, Networking, Autonomous Database, and IAM via the official OCI SDK.2367MIT
- AlicenseAqualityCmaintenanceMCP server for Oracle Cloud Infrastructure (OCI) that exposes Compute, Networking, and Object Storage operations to MCP clients, with support for multiple authentication modes, read-only enforcement, and per-call region overrides.18MIT