Skip to content

chore: add prettier #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 8, 2025
Merged
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
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
coverage
package-lock.json
23 changes: 23 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": true,
"singleQuote": false,
"printWidth": 120,
"overrides": [
{
"files": "*.json",
"options": {
"tabWidth": 2,
"printWidth": 80
}
},
{
"files": "*.md",
"options": {
"tabWidth": 2,
"printWidth": 80
}
}
]
}
8 changes: 4 additions & 4 deletions FEATURES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## Features

- [x] Login via OAuth authentication (device code)
- [x] Login via OAuth authentication (device code)
- [ ] Register via OAuth authentication (device code)
- [x] List clusters
- [ ] Create M0 cluster
- [x] List clusters
- [ ] Create M0 cluster
- [ ] Create a DBUser
- [ ] Delete a DBUser
- [ ] Connect to a cluster
- [ ] Emit telemetry events on MCP usage
- [ ] Emit telemetry events on MCP usage
43 changes: 27 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<<<<<<< HEAD

# atlas-mcp-server

TBD
=======
# TBD

# Atlas MCP Server PoC

A Model Context Protocol server for interacting with MongoDB Atlas.

Developed using the official MCP SDK https://github.com/modelcontextprotocol/typescript-sdk
Developed using the official MCP SDK https://github.com/modelcontextprotocol/typescript-sdk

## 📚 Table of Contents

- [🚀 Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
Expand All @@ -27,6 +29,7 @@ Developed using the official MCP SDK https://github.com/modelcontextprotocol/typ
## 🚀 Getting Started

### Prerequisites

- Node.js installed
- MongoDB Atlas account

Expand All @@ -45,12 +48,14 @@ npm run build
## 🔧 Troubleshooting

### Restart Server

- Run `npm run build` to re-build the server if you made changes to the code
- Press `Cmd + Shift + P` and type List MCP Servers
- Select the MCP server you want to restart
- Select the option to restart the server

### View Logs

To see MCP logs, check https://code.visualstudio.com/docs/copilot/chat/mcp-servers.

- Press `Cmd + Shift + P` and type List MCP Servers
Expand All @@ -61,19 +66,22 @@ To see MCP logs, check https://code.visualstudio.com/docs/copilot/chat/mcp-serve

We can use @modelcontextprotocol/inspector to debug the server - https://github.com/modelcontextprotocol/inspector

From the root of this repository, run:
From the root of this repository, run:

```shell
npx @modelcontextprotocol/inspector -- node dist/index.js
```

Or use the npm script:

```shell
npm run inspect
```

## 🛠️ Supported Tools

### Tool List

- `auth` - Authenticate to MongoDB Atlas
- `list-clusters` - Lists MongoDB Atlas clusters
- `list-projects` - Lists MongoDB Atlas projects
Expand All @@ -82,20 +90,22 @@ npm run inspect

### VSCode

Prerequisites:
Prerequisites:

- Use VSCode Insiders (https://code.visualstudio.com/insiders/)
- Setup copilot in VSCode Insiders

Step 1: Add the mcp server to VSCode configuration
Step 1: Add the mcp server to VSCode configuration

- Press `Cmd + Shift + P` and type `MCP: Add MCP Server` and select it.
- Select the first option for a local MCP server.
- Add the path to dist/index.js in the prompt

Step 2: Verify the created mcp file

It should look like this
```shell
It should look like this

```json
{
"servers": {
"demo-atlas-server": {
Expand All @@ -107,29 +117,31 @@ It should look like this
}
```

Step 3: Open the copilot chat and check that the toolbox icon is visible and has the mcp server listed.
Step 3: Open the copilot chat and check that the toolbox icon is visible and has the mcp server listed.

Step 4: Try running a command

- Can you list my clusters?


### Claude

Step 1: Install claude and login

```shell
brew install claude
```

Step 2: Create a configuration file for your MCP server

Open the file
```

```shell
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
```

Paste the mcp server configuration into the file
```

```json
{
"mcpServers": {
"Demo": {
Expand All @@ -139,9 +151,8 @@ Paste the mcp server configuration into the file
}
```

Step 3: Launch Claude Desktop and click on the hammer icon, the Demo MCP server should be detected. Type in the chat "show me a demo of MCP" and allow the tool to get access.
- Detailed instructions with screenshots can be found in this [document](https://docs.google.com/document/d/1_C8QBMZ5rwImV_9v4G96661OqcBk1n1SfEgKyNalv9c/edit?tab=t.2hhewstzj7ck#bookmark=id.nktw0lg0fn7t).
Step 3: Launch Claude Desktop and click on the hammer icon, the Demo MCP server should be detected. Type in the chat "show me a demo of MCP" and allow the tool to get access.

- Detailed instructions with screenshots can be found in this [document](https://docs.google.com/document/d/1_C8QBMZ5rwImV_9v4G96661OqcBk1n1SfEgKyNalv9c/edit?tab=t.2hhewstzj7ck#bookmark=id.nktw0lg0fn7t).

Note: If you make changes to your MCP server code, rebuild the project with `npm run build` and restart the server and Claude Desktop.
>>>>>>> 1599834 (chore: adds docs written by filipe into readme)
35 changes: 18 additions & 17 deletions dist/client.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import config from "./config.js";
;
export class ApiClientError extends Error {
constructor(message, response = undefined) {
super(message);
Expand All @@ -14,18 +13,20 @@ export class ApiClient {
this.saveToken = saveToken;
}
defaultOptions() {
const authHeaders = (!this.token?.access_token) ? null : {
"Authorization": `Bearer ${this.token.access_token}`
};
const authHeaders = !this.token?.access_token
? null
: {
Authorization: `Bearer ${this.token.access_token}`,
};
return {
method: "GET",
credentials: (!this.token?.access_token) ? undefined : "include",
credentials: !this.token?.access_token ? undefined : "include",
headers: {
"Content-Type": "application/json",
"Accept": "application/vnd.atlas.2025-04-07+json",
Accept: "application/vnd.atlas.2025-04-07+json",
"User-Agent": `AtlasMCP/${config.version} (${process.platform}; ${process.arch}; ${process.env.HOSTNAME || "unknown"})`,
...authHeaders
}
...authHeaders,
},
};
}
async storeToken(token) {
Expand All @@ -50,13 +51,13 @@ export class ApiClient {
headers: {
...defaultOpt.headers,
...options?.headers,
}
},
};
const response = await fetch(url, opt);
if (!response.ok) {
throw new ApiClientError(`Error calling Atlas API: ${response.statusText}`, response);
}
return await response.json();
return (await response.json());
}
async authenticate() {
const endpoint = "api/private/unauth/account/device/authorize";
Expand All @@ -65,7 +66,7 @@ export class ApiClient {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
Accept: "application/json",
},
body: new URLSearchParams({
client_id: config.clientID,
Expand All @@ -76,7 +77,7 @@ export class ApiClient {
if (!response.ok) {
throw new ApiClientError(`Failed to initiate authentication: ${response.statusText}`, response);
}
return await response.json();
return (await response.json());
}
async retrieveToken(device_code) {
const endpoint = "api/private/unauth/account/device/token";
Expand All @@ -94,7 +95,7 @@ export class ApiClient {
});
if (response.ok) {
const tokenData = await response.json();
const buf = Buffer.from(tokenData.access_token.split('.')[1], 'base64').toString();
const buf = Buffer.from(tokenData.access_token.split(".")[1], "base64").toString();
const jwt = JSON.parse(buf);
const expiry = new Date(jwt.exp * 1000);
return await this.storeToken({ ...tokenData, expiry });
Expand Down Expand Up @@ -122,7 +123,7 @@ export class ApiClient {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
Accept: "application/json",
},
body: new URLSearchParams({
client_id: config.clientID,
Expand All @@ -135,7 +136,7 @@ export class ApiClient {
throw new ApiClientError(`Failed to refresh token: ${response.statusText}`, response);
}
const data = await response.json();
const buf = Buffer.from(data.access_token.split('.')[1], 'base64').toString();
const buf = Buffer.from(data.access_token.split(".")[1], "base64").toString();
const jwt = JSON.parse(buf);
const expiry = new Date(jwt.exp * 1000);
const tokenToStore = {
Expand All @@ -151,7 +152,7 @@ export class ApiClient {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
Accept: "application/json",
"User-Agent": `AtlasMCP/${process.env.VERSION} (${process.platform}; ${process.arch}; ${process.env.HOSTNAME || "unknown"})`,
},
body: new URLSearchParams({
Expand Down Expand Up @@ -201,7 +202,7 @@ export class ApiClient {
* Get all projects for the authenticated user
*/
async listProjects() {
return await this.do('/groups');
return await this.do("/groups");
}
/**
* Get a specific project by ID
Expand Down
Loading