Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/oci-recovery-mcp-server/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Copyright (c) 2025 Oracle and/or its affiliates.

The Universal Permissive License (UPL), Version 1.0

Subject to the condition set forth below, permission is hereby granted to any
person obtaining a copy of this software, associated documentation and/or data
(collectively the "Software"), free of charge and under any and all copyright
rights in the Software, and any and all patent rights owned or freely
licensable by each licensor hereunder covering either (i) the unmodified
Software as contributed to or provided by such licensor, or (ii) the Larger
Works (as defined below), to deal in both

(a) the Software, and
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
one is included with the Software (each a "Larger Work" to which the Software
is contributed by such licensors),

without restriction, including without limitation the rights to copy, create
derivative works of, display, perform, and distribute the Software and make,
use, sell, offer for sale, import, export, have made, and have sold the
Software and the Larger Work(s), and to sublicense the foregoing rights on
either these or other terms.

This license is subject to the following condition:
The above copyright notice and either this complete permission notice or at
a minimum a reference to the UPL must be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
78 changes: 78 additions & 0 deletions src/oci-recovery-mcp-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# OCI Recovery Service MCP Server

OCI Model Context Protocol (MCP) server exposing Oracle Cloud Recovery Service operations as MCP tools.

## Features

- List Protected Databases with rich filtering (compartment, lifecycle_state, display_name, id, protection_policy_id, recovery_service_subnet_id, limit, page, sort_order, sort_by, opc_request_id, region).
- Mapping of OCI SDK models to Pydantic for safe, serializable responses.

## Install

From this repository root:

```
make build
uv pip install ./src/oci-recovery-mcp-server
```

Or directly inside the package directory:

```
cd src/oci-recovery-mcp-server
uv build
uv pip install .
```

## Usage

Run the MCP server (HTTP transport is optional):

```
# environment variables (optional)
export ORACLE_MCP_HOST=127.0.0.1
export ORACLE_MCP_PORT=7337

# run
uv run oracle.oci-recovery-mcp-server
```

The server reads OCI auth from your OCI CLI config/profile:
- Uses the profile in $OCI_CONFIG_PROFILE (defaults to DEFAULT)
- Uses security token file signer with the private key specified in config

## Tools

- get_compartment_by_name_tool(name) -> str
- list_protected_databases(compartment_id, lifecycle_state=None, display_name=None, id=None, protection_policy_id=None, recovery_service_subnet_id=None, limit=None, page=None, sort_order=None, sort_by=None, opc_request_id=None, region=None) -> list[ProtectedDatabaseSummary]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot more tools in the server file than what is included here. Can we update this list?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Updated the list.

- get_protected_database(protected_database_id, opc_request_id=None, region=None) -> ProtectedDatabase
- summarize_protected_database_health(compartment_id=None, region=None) -> ProtectedDatabaseHealthCounts
- summarize_protected_database_redo_status(compartment_id=None, region=None) -> ProtectedDatabaseRedoCounts
- summarize_backup_space_used(compartment_id=None, region=None) -> ProtectedDatabaseBackupSpaceSum
- list_protection_policies(compartment_id, lifecycle_state=None, display_name=None, id=None, limit=None, page=None, sort_order=None, sort_by=None, opc_request_id=None, region=None) -> list[ProtectionPolicySummary]
- get_protection_policy(protection_policy_id, opc_request_id=None, region=None) -> ProtectionPolicy
- list_recovery_service_subnets(compartment_id, lifecycle_state=None, display_name=None, id=None, vcn_id=None, limit=None, page=None, sort_order=None, sort_by=None, opc_request_id=None, region=None) -> list[RecoveryServiceSubnetSummary]
- get_recovery_service_subnet(recovery_service_subnet_id, opc_request_id=None, region=None) -> RecoveryServiceSubnet
- get_recovery_service_metrics(compartment_id, start_time, end_time, metricName="SpaceUsedForRecoveryWindow", resolution="1h", aggregation="max", protected_database_id=None) -> list[dict]
- list_databases(compartment_id=None, db_home_id=None, system_id=None, limit=None, page=None, sort_by=None, sort_order=None, lifecycle_state=None, db_name=None, region=None) -> list[DatabaseSummary]
- get_database(database_id, region=None) -> Database
- list_backups(compartment_id=None, database_id=None, lifecycle_state=None, type=None, limit=None, page=None, region=None) -> list[BackupSummary]
- get_backup(backup_id, region=None) -> Backup
- summarize_protected_database_backup_destination(compartment_id=None, region=None, db_home_id=None, include_last_backup_time=False) -> ProtectedDatabaseBackupDestinationSummary
- get_db_home(db_home_id, region=None) -> DatabaseHome
- list_db_systems(compartment_id=None, lifecycle_state=None, limit=None, page=None, region=None) -> list[DbSystemSummary]
- get_db_system(db_system_id, region=None) -> DbSystem

## Development

- Code style/format/lint/test tasks are managed via Makefile:
- `make build` — builds all sub-packages
- `make install` — installs all sub-packages into current environment
- `make test` — runs unit tests
- `make lint` — runs linters
- `make format` — formats code

## License

Copyright (c) 2025, Oracle and/or its affiliates.
Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl.
5 changes: 5 additions & 0 deletions src/oci-recovery-mcp-server/oracle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""
Copyright (c) 2025, Oracle and/or its affiliates.
Licensed under the Universal Permissive License v1.0 as shown at
https://oss.oracle.com/licenses/upl.
"""
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
Copyright (c) 2025, Oracle and/or its affiliates.
Licensed under the Universal Permissive License v1.0 as shown at
https://oss.oracle.com/licenses/upl.
"""

__project__ = "oracle.oci-recovery-mcp-server"
__version__ = "1.0.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@


You are an expert dashboard generator. You very well know how to generate a presentable charts for the executives .
Make sure the chart is loadable and there are no errors while loading chart.

Visualise OCI Recovery - Dashboard charts in one html document with below metrics in the given compartment.
Display the Title - OCI Recovery - Dashboard
Under the Title, mention the compartment name.
Under this compartment name add a note : Generated using Recovery Service MCP Server
Add the date of report generation

Main page ( Overview)
In first row, summarise base db systems based on backup destination - DBRS, OBJECT_STORE or UNCONFIGURED using donut chart - using tool summarise_protected_database_backup_destination . Use title - Databases categorised by backup destination. Replace DBRS with "RecoveryService” while generating the report.
In another frame, first row, second column, With title Protected Database Space : report total backup space used by protected databases - using tool summarize_backup_space_used. Note : Space used by ACTIVE/DELETE SCHEDULED protected databases
In Second Row first column, Summarise protected database based on lifecycle status using donut chart - Title - protected databases by lifecycle state. Make sure the values are based on actual data. Double check this
In Second row, summarise protected databases on health status - PROTECTED, WARNING, ALERT using donut chart - using tool summarize_protected_database_health - Title - ACTIVE protected databases by health state
In Second row, summarise protected databases on realtime redo status - ENABLED, DISABLED using donut chart - using tool summarize_protected_database_redo_status -- Title - ACTIVE protected databases by real time redo
In the Fourth row, Report the protected databases with OCID, database db unique name, health status, lifecycle state, redo status, backup space used  in tabular format . Filterable columns - Health status, Redo status , life cycle state . This data is very important. extract details very carefully from list protecetd datbase output and carefully map the columns to the OCIDs. Be very diligent while filling up this table. Dont miss the filters.


In another tab named - Backup Details
Tool to use list backups with compartment id as argument
You are an expert dashboard generator. You very well know how to generate a presentable charts for the executives .
Make sure the chart is loadable and there are no errors while loading chart. The lines in graph are clearly visible and well positioned.

Generate a line chart showing backup creation timelines for databases in the mentioned compartment. Each database is represented by a distinct line, with points marking individual backup events based on 'time_started'. The chart is styled for executive presentation, with a clean layout, legend, and tooltips.
X axis - Creation date/ Start date
Y axis - db_unique_name
Generate a line chart showing time taken by each backup for databases in the mentioned compartment. Each database is represented by a distinct line, with points marking individual backup events based on ‘duration'. If user hovers over individual points then they should gets details such as exact duration and type of backup (FULL or INCREMENTAL)  
- X axis: Creation date / Start date
- Y axis: duration_minutes.
Give your insight on
If any backup has taken more time or less time than usual pattern
Is there any backup missing in the pattern
If backup is Manually taken or LTR call that out separately

IMPORTANT: 
Make sure charts are loadable and renderable clearly in html. Double check this condition.
There should be no missing line charts
Donot add date/time on the points unless user hovers over that point.


In another tab named - Backup space usage
Tool to use get_recovery_service_metrics and resolution used 1 day.
Generate a line chart of backup space used by each protected databases in last 5 days - using tool get_recovery_service_metrics and metricName SpaceUsedForRecoveryWindow . Each protected database is represented by a distinct line with points marking individual space.
Give your insight on
If there are any anomolies in the space usage pattern.
Any other space anomoly you can think of

Add an executive KPI summary row directly below the dashboard title.

Create 4 KPI cards displayed horizontally using Bootstrap grid:

1. Total Protected Databases
2. Healthy Databases (%)
3. Redo Shipping Enabled (%)
4. Total Backup Space Used (GB)

Rules:

- Use existing dashboard data to calculate KPI values.
- KPI cards must be visually compact and equal height.
- Each KPI card should contain:
- Small uppercase label
- Large bold metric value
- Optional subtext (e.g. "of 3 databases")

Styling:

- Use soft card backgrounds with rounded corners.
- Center-align KPI content.
- Use large font (2–2.5rem) for KPI numbers.
- Use subtle shadows.
- Maintain spacing with Bootstrap g-4.

Layout:

- KPI row must appear ABOVE all charts.
- Dashboard width remains 75vw.
- On mobile, stack KPI cards vertically.

Data logic:

- Total Protected Databases = count of protected databases.
- Healthy % = (PROTECTED / total) * 100.
- Redo Enabled % = (ENABLED / total) * 100.
- Total Backup Space = sum of space used.

After KPIs, keep charts as secondary visual detail.


IMPORTANT

Layout rules for HTML dashboard:

- Wrap all content in a .dashboard-container:
width: 75vw;
max-width: 1200px;
margin: 0 auto;
- Center the dashboard horizontally.
- Do NOT use full screen width.
- On mobile (<768px), expand dashboard to 95vw.

Chart container sizing:

- Do NOT use a single default height for all charts.
- Overview donut charts MUST be compact:
height: 260px.
- Timeline / line charts:
height: 360px.
- Space usage charts:
height: 300px.
- Apply CSS classes per chart type (overview-donut, timeline-chart, space-chart).
- Ensure donuts appear compact and not vertically stretched.

When using Chart.js:

- NEVER use custom HTML legends.
- NEVER use absolute positioning over canvas.
- Always use native Chart.js legend positioned on the right.
- Add layout.padding = 20 to every chart.
- For doughnut charts:
cutout: '65%'
radius: '85%'
- Ensure charts fit inside containers without clipping.
- Avoid overlapping elements.
- Maintain clean spacing between panels.
- Optimize layout for presentation-quality visuals.
Make sure chart sizes are equal and fit well inside demarcation.
Make sure there are no rendering issues
Dont generate trucated html file.
Make sure its a complete file wihtout any syntax issues
Make sure legends are written on the rightside of donut chart and with in frame
Show all the legends and next to legends mention the count as well in brackets
Make sure titles are on the top of the donut chart .
Makesure title, donut chart and legends fit with in the frame

Always render charts for every tab
Include required JS adapters
Initialize charts after tab activation


Use soft colors in the chart - executive appealing colors
Demarcate between the rows Since this is a dashboard make sure user gets the visbility of most charts without scrolling.
Create a responsive layout minimizing scrolling



Loading
Loading