mirror of
https://github.com/modelcontextprotocol/servers.git
synced 2026-02-19 11:54:58 -05:00
Refactor: Remove Oracle server implementation and related files, moved to Community Servers
- Deleted the Oracle server Dockerfile, README, demo prompts, and configuration files. - Removed the Oracle server package.json and TypeScript configuration. - Updated package.json to remove dependency on the Oracle server.
This commit is contained in:
@@ -604,6 +604,7 @@ A growing set of community-developed and maintained servers demonstrates various
|
||||
- **[Office-Word-MCP-Server](https://github.com/GongRzhe/Office-Word-MCP-Server)** - A Model Context Protocol (MCP) server for creating, reading, and manipulating Microsoft Word documents.
|
||||
- **[Okta](https://github.com/kapilduraphe/okta-mcp-server)** - Interact with Okta API.
|
||||
- **[OneNote](https://github.com/rajvirtual/MCP-Servers/tree/master/onenote)** - (by Rajesh Vijay) An MCP server that connects to Microsoft OneNote using the Microsoft Graph API. Reading notebooks, sections, and pages from OneNote,Creating new notebooks, sections, and pages in OneNote.
|
||||
- **[Oracle](https://github.com/marcelo-ochoa/servers)** (by marcelo-ochoa) - Oracle Database integration in NodeJS with configurable access controls, query explain, stats and schema inspection
|
||||
- **[Open Strategy Partners Marketing Tools](https://github.com/open-strategy-partners/osp_marketing_tools)** - Content editing codes, value map, and positioning tools for product marketing.
|
||||
- **[OpenAI WebSearch MCP](https://github.com/ConechoAI/openai-websearch-mcp)** - This is a Python-based MCP server that provides OpenAI `web_search` build-in tool.
|
||||
- **[OpenAPI](https://github.com/snaggle-ai/openapi-mcp-server)** - Interact with [OpenAPI](https://www.openapis.org/) APIs.
|
||||
|
||||
1659
package-lock.json
generated
1659
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -20,9 +20,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/server-everything": "*",
|
||||
"@modelcontextprotocol/server-filesystem": "*",
|
||||
"@modelcontextprotocol/server-memory": "*",
|
||||
"@modelcontextprotocol/server-oracle": "*",
|
||||
"@modelcontextprotocol/server-filesystem": "*",
|
||||
"@modelcontextprotocol/server-sequential-thinking": "*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
FROM node:22-alpine AS builder
|
||||
|
||||
COPY src/oracle /app
|
||||
COPY tsconfig.json /tsconfig.json
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=cache,target=/root/.npm npm install
|
||||
|
||||
RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
|
||||
|
||||
FROM node:22-alpine AS release
|
||||
|
||||
COPY --from=builder /app/dist /app/dist
|
||||
COPY --from=builder /app/package.json /app/package.json
|
||||
COPY --from=builder /app/package-lock.json /app/package-lock.json
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm ci --ignore-scripts --omit-dev
|
||||
|
||||
ENTRYPOINT ["node", "dist/index.js"]
|
||||
@@ -1,191 +0,0 @@
|
||||
# Oracle Database
|
||||
|
||||
A Model Context Protocol server that provides read-only access to Oracle Database. This server enables LLMs to inspect database schemas, execute and explain read-only queries.
|
||||
|
||||
## Components
|
||||
|
||||
### Tools
|
||||
|
||||
- **query**
|
||||
- Execute read-only SQL queries against the connected Oracle Database
|
||||
- Input: `sql` (string): The SQL query to execute
|
||||
- All queries are executed within a READ ONLY transaction
|
||||
|
||||
- **explain**
|
||||
- Explain plan SQL queries against the connected Oracle Database
|
||||
- Input: `sql` (string): The SQL query to execute
|
||||
- Requires GRANT SELECT_CATALOG_ROLE TO your_user;
|
||||
|
||||
- **stats**
|
||||
- Get statistics for a given table on current connected schema
|
||||
- Input: `name` (string): The table name
|
||||
- Table owner is equal to USER SQL function returning value
|
||||
|
||||
- **connect**
|
||||
- Reconnect using new credentials
|
||||
- Input: `connectionString` (string): SQLNet connect string for example host.docker.internal:1521/freepdb1
|
||||
- Input: `user` (string): Username for example scott
|
||||
- Input: `password` (string): Password, for example tiger
|
||||
|
||||
### Resources
|
||||
|
||||
The server provides schema information for each table in the Oracle Database current connected user:
|
||||
|
||||
- **Table Schemas** (`oracle://USER/<table>/schema`)
|
||||
- JSON schema information for each table
|
||||
- Includes column names and data types
|
||||
- Automatically discovered from Oracle Database metadata
|
||||
|
||||
## Usage with Claude Desktop
|
||||
|
||||
To use this server with the Claude Desktop app, add the following configuration to the "mcpServers" section of your `claude_desktop_config.json`:
|
||||
|
||||
### Docker
|
||||
|
||||
* when running docker on macOS, use host.docker.internal if the server is running on the host network (eg localhost)
|
||||
* username/password must be passed as environment variables
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"oracle": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"ORACLE_USER=scott",
|
||||
"-e",
|
||||
"ORACLE_PASSWORD=tiger",
|
||||
"mcp/oracle",
|
||||
"host.docker.internal:1521/freepdb1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### NPX
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"oracle": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-oracle",
|
||||
"localhost:1521/freepdb1"
|
||||
],
|
||||
"env": {
|
||||
"ORACLE_USER": "scott",
|
||||
"ORACLE_PASSWORD": "tiger"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `/freepdb1` with your database name.
|
||||
|
||||
### Demo Prompts
|
||||
|
||||
Sample prompts using the Oracle Database sample HR schema and
|
||||
[Oracle Database 23ai Free embedded database - Faststart - Docker Desktop Extension](https://open.docker.com/extensions/marketplace?extensionId=mochoa/oraclefree-docker-extension) .
|
||||
|
||||
- query SELECT COUNTRY_NAME, CITY, COUNT(DEPARTMENT_ID)
|
||||
FROM COUNTRIES JOIN LOCATIONS USING (COUNTRY_ID) JOIN DEPARTMENTS USING (LOCATION_ID)
|
||||
WHERE DEPARTMENT_ID IN
|
||||
(SELECT DEPARTMENT_ID FROM EMPLOYEES
|
||||
GROUP BY DEPARTMENT_ID
|
||||
HAVING COUNT(DEPARTMENT_ID)>5)
|
||||
GROUP BY COUNTRY_NAME, CITY
|
||||
- explain the execution plan
|
||||
- visualize above execution plan
|
||||
- get stats of COUNTRIES, LOCATIONS and DEPARTMENTS
|
||||
- based on above table and index stats rewrite above query with a better execution plan
|
||||
- visualize original and rewritten execution plan
|
||||
|
||||
See in action using Claude Desktop App
|
||||
|
||||

|
||||
|
||||
### Using Docker AI
|
||||
|
||||
[Ask Gordon](https://docs.docker.com/desktop/features/gordon/) is an AI assistant designed to streamline your Docker workflow by providing contextual assistance tailored to your local environment. Currently in Beta and available in Docker Desktop version 4.38.0 or later, Ask Gordon offers intelligent support for various Docker-related tasks.
|
||||
|
||||
```sh
|
||||
% cd src/oracle
|
||||
% docker ai 'stats for table countries'
|
||||
|
||||
• Calling stats ✔️
|
||||
|
||||
Here are the statistics for the COUNTRIES table:
|
||||
|
||||
### Table Statistics:
|
||||
|
||||
• Owner: HR
|
||||
• Table Name: COUNTRIES
|
||||
• Number of Rows: 25
|
||||
• Average Row Length: 16 bytes
|
||||
• Last Analyzed: 2025-03-10 22:00:38
|
||||
|
||||
### Index Statistics:
|
||||
|
||||
• Index Name: COUNTRY_C_ID_PK
|
||||
• B-Level: 0
|
||||
• Leaf Blocks: 1
|
||||
• Distinct Keys: 25
|
||||
• Number of Rows: 25
|
||||
• Clustering Factor: 0
|
||||
• Last Analyzed: 2025-03-10 22:00:38
|
||||
|
||||
### Column Statistics:
|
||||
|
||||
1. COUNTRY_ID:
|
||||
|
||||
• Number of Distinct Values: 25
|
||||
• Density: 0.04
|
||||
• Histogram: NONE
|
||||
• Last Analyzed: 2025-03-10 22:00:38
|
||||
|
||||
2. COUNTRY_NAME:
|
||||
|
||||
• Number of Distinct Values: 25
|
||||
• Density: 0.04
|
||||
• Histogram: NONE
|
||||
• Last Analyzed: 2025-03-10 22:00:38
|
||||
|
||||
3. REGION_ID:
|
||||
|
||||
• Number of Distinct Values: 5
|
||||
• Density: 0.02
|
||||
• Histogram: FREQUENCY
|
||||
• Last Analyzed: 2025-03-10 22:00:38
|
||||
```
|
||||
|
||||
Using this sample gordon-mcp.yml file in a current directory:
|
||||
|
||||
```yml
|
||||
services:
|
||||
time:
|
||||
image: mcp/time
|
||||
oracle:
|
||||
image: mcp/oracle
|
||||
command: ["host.docker.internal:1521/freepdb1"]
|
||||
environment:
|
||||
- ORACLE_USER=scott
|
||||
- ORACLE_PASSWORD=tiger
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
Docker:
|
||||
|
||||
```sh
|
||||
docker build -t mcp/oracle -f src/oracle/Dockerfile .
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 MiB |
@@ -1,9 +0,0 @@
|
||||
services:
|
||||
time:
|
||||
image: mcp/time
|
||||
oracle:
|
||||
image: mcp/oracle
|
||||
command: ["host.docker.internal:1521/freepdb1"]
|
||||
environment:
|
||||
- ORACLE_USER=hr
|
||||
- ORACLE_PASSWORD=hr_2025
|
||||
@@ -1,398 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
CallToolRequestSchema,
|
||||
ListResourcesRequestSchema,
|
||||
ListToolsRequestSchema,
|
||||
ReadResourceRequestSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import oracledb from "oracledb";
|
||||
|
||||
const server = new Server(
|
||||
{
|
||||
name: "example-servers/oracle",
|
||||
version: "0.1.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
resources: {},
|
||||
tools: {},
|
||||
prompts: {}, // Add this line to indicate support for prompts
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const prompts = [
|
||||
{ id: 1, text: "query select * from COUNTRIES" },
|
||||
{ id: 2, text: "explain select * from COUNTRIES" },
|
||||
{ id: 3, text: "stats COUNTRIES" },
|
||||
{ id: 4, text: "connect to Oracle using an string like host.docker.internal:1521/freepdb1 user name and password" }
|
||||
];
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length === 0) {
|
||||
console.error("Please provide an Oracle database connection string as a command-line argument");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const connectionString = args[0];
|
||||
|
||||
if (!process.env.ORACLE_USER) {
|
||||
console.error("Error: Environment variable ORACLE_USER must be set.");
|
||||
process.exit(1);
|
||||
}
|
||||
const resourceBaseUrl = new URL("oracle://" + process.env.ORACLE_USER.toUpperCase());
|
||||
resourceBaseUrl.protocol = "oracle:";
|
||||
resourceBaseUrl.password = "";
|
||||
|
||||
const SCHEMA_PATH = "schema";
|
||||
|
||||
// Initialize the pool outside of request handlers.
|
||||
let pool: oracledb.Pool | undefined = undefined;
|
||||
|
||||
// Helper function to initialize the connection pool
|
||||
async function initializePool(connectionString: string) {
|
||||
const dbUser = process.env.ORACLE_USER;
|
||||
const dbPassword = process.env.ORACLE_PASSWORD;
|
||||
|
||||
if (!dbUser || !dbPassword) {
|
||||
console.error(
|
||||
"Error: Environment variables ORACLE_USER and ORACLE_PASSWORD must be set.",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
//console.log("Initializing OracleDB connection pool...");
|
||||
pool = await oracledb.createPool({
|
||||
user: dbUser,
|
||||
password: dbPassword,
|
||||
connectionString,
|
||||
poolMin: 4,
|
||||
poolMax: 10,
|
||||
poolIncrement: 1,
|
||||
queueTimeout: 60000,
|
||||
});
|
||||
//console.log("OracleDB connection pool initialized successfully.");
|
||||
} catch (err) {
|
||||
console.error("connectionString:", connectionString);
|
||||
console.error("Error initializing connection pool:", err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
||||
if (!pool) {
|
||||
throw new Error("Oracle connection pool not initialized.");
|
||||
}
|
||||
|
||||
let connection;
|
||||
try {
|
||||
connection = await pool.getConnection();
|
||||
const result = await connection.execute<{ TABLE_NAME: string }>(
|
||||
`SELECT table_name as "TABLE_NAME" FROM user_tables`,
|
||||
[], // binding parameters
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
return {
|
||||
resources: result.rows!.map((row) => ({
|
||||
uri: new URL(`${row.TABLE_NAME}/${SCHEMA_PATH}`, resourceBaseUrl).href,
|
||||
mimeType: "application/json",
|
||||
name: `"${row.TABLE_NAME}" database schema`,
|
||||
})),
|
||||
};
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (err) {
|
||||
console.error("Error closing Oracle connection:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
||||
if (!pool) {
|
||||
throw new Error("Oracle connection pool not initialized.");
|
||||
}
|
||||
|
||||
const resourceUrl = new URL(request.params.uri);
|
||||
|
||||
const pathComponents = resourceUrl.pathname.split("/");
|
||||
const schema = pathComponents.pop();
|
||||
const tableName = pathComponents.pop();
|
||||
|
||||
if (schema !== SCHEMA_PATH) {
|
||||
throw new Error("Invalid resource URI");
|
||||
}
|
||||
|
||||
let connection;
|
||||
try {
|
||||
connection = await pool.getConnection();
|
||||
const result = await connection.execute<{ METADATA: string }>(
|
||||
`select dbms_developer.get_metadata (name => UPPER(:tableName)) as metadata from dual`, [tableName], { outFormat: oracledb.OUT_FORMAT_OBJECT });
|
||||
|
||||
return {
|
||||
contents: [
|
||||
{
|
||||
uri: request.params.uri,
|
||||
mimeType: "application/json",
|
||||
text: JSON.stringify(result.rows?.[0]?.METADATA, null, 2),
|
||||
},
|
||||
],
|
||||
isError: false,
|
||||
};
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (err) {
|
||||
console.error("Error closing Oracle connection:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||
return {
|
||||
tools: [
|
||||
{
|
||||
name: "query",
|
||||
description: "Run a read-only SQL query",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
sql: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "explain",
|
||||
description: "Explain Plan for SQL query",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
sql: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "stats",
|
||||
description: "Stats for SQL object",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "connect",
|
||||
description: "Switch to a new Oracle DB connection on the fly",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionString: { type: "string" },
|
||||
user: { type: "string" },
|
||||
password: { type: "string" },
|
||||
},
|
||||
required: ["connectionString", "user", "password"],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
if (!pool) {
|
||||
throw new Error("Oracle connection pool not initialized.");
|
||||
}
|
||||
|
||||
if (request.params.name === "query") {
|
||||
const sql = typeof request.params.arguments?.sql === "string"
|
||||
? request.params.arguments.sql.replace(/;\s*$/, "")
|
||||
: "";
|
||||
|
||||
let connection;
|
||||
try {
|
||||
connection = await pool.getConnection();
|
||||
await connection.execute("SET TRANSACTION READ ONLY");
|
||||
const result = await connection.execute(sql, [], { outFormat: oracledb.OUT_FORMAT_OBJECT });
|
||||
return {
|
||||
content: [{ type: "text", text: JSON.stringify(result.rows, null, 2) }],
|
||||
isError: false,
|
||||
};
|
||||
} catch (error) {
|
||||
throw error;
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (err) {
|
||||
console.warn("Could not close connection:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (request.params.name === "explain") {
|
||||
const sql = typeof request.params.arguments?.sql === "string"
|
||||
? request.params.arguments.sql.replace(/;\s*$/, "")
|
||||
: "";
|
||||
|
||||
let connection;
|
||||
try {
|
||||
connection = await pool.getConnection();
|
||||
await connection.execute("EXPLAIN PLAN FOR " + sql);
|
||||
const result = await connection.execute("SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, NULL, 'ALL'))", [], { outFormat: oracledb.OUT_FORMAT_OBJECT });
|
||||
return {
|
||||
content: [{ type: "text", text: JSON.stringify(result.rows, null, 2) }],
|
||||
isError: false,
|
||||
};
|
||||
} catch (error) {
|
||||
throw error;
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (err) {
|
||||
console.warn("Could not close connection:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (request.params.name === "stats") {
|
||||
const tableName = request.params.arguments?.name as string;
|
||||
let connection;
|
||||
try {
|
||||
connection = await pool.getConnection();
|
||||
const result = await connection.execute<{ STATS_JSON: string }>(`SELECT JSON_OBJECT(
|
||||
'table_stats' VALUE (
|
||||
SELECT JSON_OBJECT(
|
||||
'owner' VALUE owner,
|
||||
'table_name' VALUE table_name,
|
||||
'num_rows' VALUE num_rows,
|
||||
'blocks' VALUE blocks,
|
||||
'empty_blocks' VALUE empty_blocks,
|
||||
'avg_row_len' VALUE avg_row_len,
|
||||
'last_analyzed' VALUE TO_CHAR(last_analyzed, 'YYYY-MM-DD HH24:MI:SS')
|
||||
)
|
||||
FROM dba_tab_statistics
|
||||
WHERE owner = UPPER(USER) AND table_name = UPPER(:tableName)
|
||||
),
|
||||
'index_stats' VALUE (
|
||||
SELECT JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'index_name' VALUE index_name,
|
||||
'blevel' VALUE blevel,
|
||||
'leaf_blocks' VALUE leaf_blocks,
|
||||
'distinct_keys' VALUE distinct_keys,
|
||||
'num_rows' VALUE num_rows,
|
||||
'clustering_factor' VALUE clustering_factor,
|
||||
'last_analyzed' VALUE TO_CHAR(last_analyzed, 'YYYY-MM-DD HH24:MI:SS')
|
||||
)
|
||||
)
|
||||
FROM dba_ind_statistics
|
||||
WHERE table_owner = UPPER(USER) AND table_name = UPPER(:tableName)
|
||||
),
|
||||
'column_stats' VALUE (
|
||||
SELECT JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'column_name' VALUE column_name,
|
||||
'num_distinct' VALUE num_distinct,
|
||||
'density' VALUE density,
|
||||
'histogram' VALUE histogram,
|
||||
'last_analyzed' VALUE TO_CHAR(last_analyzed, 'YYYY-MM-DD HH24:MI:SS')
|
||||
)
|
||||
)
|
||||
FROM dba_tab_col_statistics
|
||||
WHERE owner = UPPER(USER) AND table_name = UPPER(:tableName)
|
||||
)
|
||||
) AS stats_json
|
||||
FROM dual`, [tableName,tableName,tableName], { outFormat: oracledb.OUT_FORMAT_OBJECT });
|
||||
return {
|
||||
content: [{ type: "text", text: result.rows?.[0]?.STATS_JSON }],
|
||||
isError: false,
|
||||
};
|
||||
} catch (error) {
|
||||
throw error;
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (err) {
|
||||
console.warn("Could not close connection:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (request.params.name === "connect") {
|
||||
const newConnectionString = request.params.arguments?.connectionString;
|
||||
const newUser = request.params.arguments?.user;
|
||||
const newPassword = request.params.arguments?.password;
|
||||
if (
|
||||
typeof newConnectionString !== "string" || !newConnectionString ||
|
||||
typeof newUser !== "string" || !newUser ||
|
||||
typeof newPassword !== "string" || !newPassword
|
||||
) {
|
||||
return {
|
||||
content: [{ type: "text", text: "Missing or invalid connectionString, user, or password argument." }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
try {
|
||||
if (pool) {
|
||||
try {
|
||||
await pool.close(0); // Close existing pool immediately
|
||||
} catch (err) {
|
||||
// Log but continue
|
||||
console.warn("Error closing previous pool:", err);
|
||||
}
|
||||
}
|
||||
// Override env vars for this session
|
||||
process.env.ORACLE_USER = newUser;
|
||||
process.env.ORACLE_PASSWORD = newPassword;
|
||||
await initializePool(newConnectionString);
|
||||
return {
|
||||
content: [{ type: "text", text: `Successfully connected to new Oracle DB: ${newConnectionString} as user ${newUser}` }],
|
||||
isError: false,
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
content: [{ type: "text", text: `Failed to connect: ${err}` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
throw new Error(`Unknown tool: ${request.params.name}`);
|
||||
});
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
const PromptsListRequestSchema = z.object({
|
||||
method: z.literal("prompts/list"),
|
||||
params: z.object({}),
|
||||
});
|
||||
|
||||
server.setRequestHandler(PromptsListRequestSchema, async () => {
|
||||
return {
|
||||
prompts,
|
||||
};
|
||||
});
|
||||
|
||||
async function runServer() {
|
||||
await initializePool(connectionString); // Initialize the pool before starting the server
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
}
|
||||
|
||||
runServer().catch(console.error);
|
||||
|
||||
process.stdin.on("close", () => {
|
||||
console.error("Oracle MCP Server closed");
|
||||
server.close();
|
||||
process.exit(0);
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"name": "@modelcontextprotocol/server-oracle",
|
||||
"version": "0.6.2",
|
||||
"description": "MCP server for interacting with Oracle databases",
|
||||
"license": "MIT",
|
||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||
"homepage": "https://modelcontextprotocol.io",
|
||||
"bugs": "https://github.com/modelcontextprotocol/servers/issues",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"mcp-server-oracle": "dist/index.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && shx chmod +x dist/*.js",
|
||||
"prepare": "npm run build",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "1.0.1",
|
||||
"oracledb": "^6.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/oracledb": "^6.1.0",
|
||||
"shx": "^0.3.4",
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user