Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
891f378
feat: add axios in package.json
Sep 1, 2025
303df68
fix: use log level defined in LOG_LEVEL
Sep 1, 2025
e49d230
feat: first impl of auth2 flow
Sep 1, 2025
67e568d
feat: more TODOs and code clean up
Sep 2, 2025
ab66d0a
refactor: more oauthRotuer in separate folder
Sep 5, 2025
e1af2a8
feat:create internal/mcp route, /mcp route now requires auth method
Sep 5, 2025
361c249
refactor: env var PORT instead of HTTP_PORT
Sep 5, 2025
4e9b444
feat: token handling from header in HTTPClient
Sep 5, 2025
3c0695f
fix: use CONSOLE_HOST to handle requests
Sep 5, 2025
f7fa96c
refactor: additional cleanup
Sep 8, 2025
87b36b4
1.0.6
Sep 8, 2025
b0962aa
chore: temp tag v1.1.0-exp.1
Sep 8, 2025
d78b96e
fix: unit tests
Sep 8, 2025
4809fb1
chore: 1.1.0-exp.2
Sep 8, 2025
dee0bc8
fix: auth links
Sep 8, 2025
c766f67
chore: 1.1.0-exp.3
Sep 8, 2025
6a13555
chore: 1.1.0-exp.4
Sep 8, 2025
118be58
chore: 1.1.0-exp.5
Sep 8, 2025
b81cced
chore: 1.1.0-exp.6
Sep 8, 2025
897a374
chore: 1.1.0-exp.7
Sep 8, 2025
a53ac1e
fix: lint rules
Sep 10, 2025
6abd537
feat: @fastify/formbody to support formdata in post requests
Sep 11, 2025
6a5229f
feat: clientCredentialsManager
Sep 11, 2025
16fa7d7
feat: routes refactor
Sep 11, 2025
222b3ac
fix: tests
Sep 11, 2025
648cf6f
refactor: types
Sep 12, 2025
2d81f4d
feat: tests for ClientCredentialsManager
Sep 12, 2025
ab6986c
refactor: more unit tests
Sep 12, 2025
e0b283b
fix: restored healthz/ready routes
Sep 12, 2025
6f46624
fix: linting
Sep 12, 2025
e40ea44
fix: updated package.json and lock
Sep 12, 2025
7e76c48
fix: tests in status routes
Sep 12, 2025
82a267c
refactor: headers management
Sep 12, 2025
0a1196f
fix: headers used in internal requests
Sep 12, 2025
f72fc52
fix: include code_challenge_methods_supported
Sep 12, 2025
5e9c38e
client registration timeout to 300 seconds
Sep 12, 2025
2d2f2e2
refactor and clean up here and there
Sep 12, 2025
27e8989
feat: wellKnownRouter tests
Sep 12, 2025
2fc964b
tests in oauthRouter
Sep 12, 2025
96c6900
feat: CLIENT_EXPIRY_DURATION env var
Sep 12, 2025
1e0e538
feat: docs revised
Sep 12, 2025
8ca637d
fix: restore package version
Sep 12, 2025
aae5459
Merge branch 'main' into feat/oauth2-support
Sep 12, 2025
ac82e97
additional instructions on the mcp routes
Sep 15, 2025
d5c3a25
Merge branch 'main' into feat/oauth2-support
Sep 16, 2025
f3ecd90
Update src/server/statusRoutes.test.ts
ThisIsDemetrio Sep 17, 2025
8629fee
fix: lint
Sep 17, 2025
7e825ab
feat: auth flow communicates to okta
Sep 22, 2025
ee5dec0
fix: additional tests
Sep 22, 2025
e137d50
fix: tests
Sep 22, 2025
bb41305
fix: avoid failure in stdio run because of header updates
Sep 22, 2025
1490115
Merge branch 'main' into feat/oauth2-support
Sep 26, 2025
66a906d
Update src/index.ts
ThisIsDemetrio Sep 26, 2025
fb7ba37
fix: small import
Sep 26, 2025
f516057
chore: v1.1.0-exp15
Sep 26, 2025
2bad267
Revert "chore: v1.1.0-exp15"
Sep 29, 2025
20a006a
Revert "fix: avoid failure in stdio run because of header updates"
Sep 29, 2025
ce25a01
Revert "fix: tests"
Sep 29, 2025
8ad29cb
Revert "fix: additional tests"
Sep 29, 2025
b6827f2
Revert "feat: auth flow communicates to okta"
Sep 29, 2025
224e2b1
fix: restored /token endpoint to refreshToken
Sep 29, 2025
61ba63c
feat: minor updates after review
Sep 29, 2025
71ef10e
fix: documentation
Sep 30, 2025
4d1abca
Merge branch 'main' into feat/oauth2-support
Oct 3, 2025
632260d
Merge branch 'main' into feat/oauth2-support
Oct 3, 2025
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
86 changes: 54 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,23 @@

## Introduction

The Mia-Platform Console MCP Server is a [Model Context Protocol (MCP)] server that provides seamless integration
The Mia-Platform Console MCP Server is a [Model Context Protocol (MCP)](mcp-intro) server that provides seamless integration
with Mia-Platform Console APIs, enabling advanced automation and interaction capabilities for developers and tools.

## Prerequisites

1. To run the server in a container, you will need to have [Docker] installed.
1. Once Docker is installed, you will also need to ensure Docker is running.
1. Lastly you will need to a way ot authenticate to your Mia-Platform Console installation, you either have to:
- [Create a Mia-Platform Service Account] with `Client Secret Basic`
authorization mode (the only one supported at this time)
the `Client Secret Basic` one.
- Use miactl authentication: if you have [`miactl`][miactl] installed you can run any command to login,
the same session will then be used by the mcp server to authenticate.

> [!WARNING]
> When using miactl session, auto-refresh by the MCP Server is not currently supported,
> once the session created with miactl expires you have to refresh it with miactl again.
---
> [!IMPORTANT]
> When using miactl session, the host you provide to the MCP Server **MUST** be the exact same as the one
> you have logged in with miactl, including scheme and any possible trailing slash.
To use the Mia-Platform Console MCP Server in your client (such as Visual Studio Code, Claude Desktop, Cursor, Gemini CLI or others), you first need to have a valid account on the Mia-Platform Console instance you want to communicate with. You will be required also to include the instance host address you in the environment variable named `CONSOLE_HOST`.

### How to Run
You may decide to access via:

- Service Account to perform machine-2-machine authentication and have full access to the MCP capabilities to perform operations on the Company where the S.A. has been created (for more information, visit [our official documentation on how to create a Mia-Platform Service Account](docs-create-service-account)). If you do so, you need to include the environment variables `MIA_PLATFORM_CLIENT_ID` and `MIA_PLATFORM_CLIENT_SECRET`.
- Using your own credentials: Mia-Platform Console MCP Server follows the [Model Context Protocol specifications on authentication](mcp-specs-auth) using OAuth2.1 and Dynamic Client Registration: clients that follow that specifications will be able to discover the authentication endpoints of the selected Mia-Platform instance you want to access to and guide you to perform the log in.

To run the MCP server on your machine you can follow the instructions in the [Setup Documentation]
### How to Run

### Run from sources
You can run stable versions of the Mia-Platform Console MCP Server using [Docker](Docker). You can get detailed guide using the [following guide](20-setup).

If you don't have Docker installed, you can use NPM and Node.js for running it locally. Once you have cloned the
If you don't have Docker installed, or you simply wish to run it locally, you can use NPM and Node.js. Once you have cloned the
project you can run the commands:

```sh
Expand All @@ -60,19 +48,53 @@ Once these steps are completed you can setup the MCP server using the `node` com
"start",
"--stdio",
"--host=https://console.cloud.mia-platform.eu"
],
"env": {
"MIA_PLATFORM_CLIENT_ID": "<YOUR_CLIENT_ID>",
"MIA_PLATFORM_CLIENT_SECRET": "<YOUR_CLIEND_SECRET>"
}
]
}
}
}
}
```

> [!TIP]
> If you have a `.env` file configured with your credentials, you can omit the `env` section from the configuration above as the server will automatically load the environment variables.
:::tip

Alternatively, you start the service after the build with the following command:

```sh
node mcp-server start
```

Then add the mcp server to your client simply including the url. As example for VS Code:

```json
{
"mcp": {
"servers": {
"mia-platform-console": {
"type": "http",
"url": "http://localhost:3000/console-mcp-server/mcp"
}
}
}
}
```

Instead of `3000`, please include the port defined in the environment variable `PORT`. More detail in the [Environment Variables](#environment-variables) section.

:::

### Environment Variables

Environment variables located inside a file named `.env` are automatically included at service startup.

| Variable Name | Description | Required | Default Value |
|---------------|-------------|----------|---------------|
| `LOG_LEVEL` | Log level of the application | No | `info` |
| `PORT` | Port number for the HTTP server | No | `3000` |
| `CONSOLE_HOST` | The host address of the Mia-Platform Console instance | Yes | - |
| `MIA_PLATFORM_CLIENT_ID` | Client ID for Service Account authentication | No | - |
| `MIA_PLATFORM_CLIENT_SECRET` | Client secret for Service Account authentication | No | - |
| `CLIENT_EXPIRY_DURATION` | Duration in seconds of clients generated with the DCR authentication flow. After this time, the client will be expired and cannot be used anylonger. | No | `300` |


## Local Development

Expand Down Expand Up @@ -123,10 +145,10 @@ node --test --import tsx <FILE_PATH>
[pipeline-link]: https://github.com/mia-platform/console-mcp-server/actions
[build-svg]: https://img.shields.io/github/actions/workflow/status/mia-platform/console-mcp-server/build-and-test.yaml
[license-svg]: https://img.shields.io/github/license/mia-platform/console-mcp-server
[Model Context Protocol (MCP)]: https://modelcontextprotocol.io/introduction
[mcp-intro]: https://modelcontextprotocol.io/introduction
[mcp-specs-auth]: https://modelcontextprotocol.io/specification/2025-06-18
[Docker]: https://www.docker.com/
[Setup Documentation]: /docs/20_setup.md
[Create a Mia-Platform Service Account]: https://docs.mia-platform.eu/docs/development_suite/identity-and-access-management/manage-service-accounts
[20-setup]: /docs/20_setup.md
[docs-create-service-account]: https://docs.mia-platform.eu/docs/development_suite/identity-and-access-management/manage-service-accounts
[nvm]: https://github.com/nvm-sh/nvm
[mise]: https://mise.jdx.dev
[miactl]: https://github.com/mia-platform/miactl
15 changes: 15 additions & 0 deletions default.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
# Application port
PORT=3000
# Fastify log level
LOG_LEVEL=info

# Mia-Platform Console instance to communicate with (required)
CONSOLE_HOST=<CONSOLE_URL>

# If you have a Mia-Platform Service Account on your company, please include
# the clientId and clientSecret here to perform M2M authentication.
# If these values are absent, OAuth2 authentication flow will be performed.
MIA_PLATFORM_CLIENT_ID=<SERVICE_ACCOUNT_CLIENT_ID>
MIA_PLATFORM_CLIENT_SECRET=<SERVICE_ACCOUNT_CLIENT_SECRET>

# In case OAuth2 authentication, you can set the time in seconds in which the client credentials
# generated will expire (optional; default: 300)
CLIENT_EXPIRY_DURATION=300
43 changes: 14 additions & 29 deletions docs/20_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,26 @@
### Prerequisites

1. To run the server in a container, you will need to have [Docker] installed.
1. Once Docker is installed, you will also need to ensure Docker is running.
1. Pull the docker image `docker pull ghcr.io/mia-platform/console-mcp-server`
1. Login to Mia-Platform. You have two options:
- (a) *User Authentication* - Use miactl authentication: if you have [`miactl`][miactl] installed you can login and
the same session will then be used by the mcp server to authenticate. To login just type `miactl company list`,
or any other miactl command, the browser will be opened and you can use your credentials to login. You will be
able to access to all companies and projects that have been granted to your user.
- (b) *Service Account* - [Create a Mia-Platform Service Account] with `Client Secret Basic` authorization mode
(the only one supported at this time) the `Client Secret Basic` one. In that case you can access to just one
company at a time.

> [!WARNING]
> When using miactl session, auto-refresh by the MCP Server is not currently supported,
> once the session created with miactl expires you have to refresh it with miactl again.
---
> [!IMPORTANT]
> When using miactl session, the host you provide to the MCP Server **MUST** be the exact same as the one
> you have logged in with miactl, including scheme and any possible trailing slash.
2. Once Docker is installed, you will also need to ensure Docker is running.
3. Pull the docker image `docker pull ghcr.io/mia-platform/console-mcp-server` at your own preferred version (or `latest` if you want to try the nightly build)
4. Login to Mia-Platform. You have two options:
- (a) *Service Account* - [Create a Mia-Platform Service Account] with `Client Secret Basic` authorization mode (the only one supported at this time) the `Client Secret Basic` one. In that case you can access to just one company at a time.
- (b) *User Authentication* - Assuming you have a valid Mia Platform account, you can simply omit the information about the service account and - at the MCP startup - your client will ask you to open for you a webpage where you can execute the login.


### VS Code

For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by
pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`. Optionally, you can add it to a file
called `.vscode/mcp.json` in your workspace.
For manual installation, add the following JSON block to your MCP Server list file in VS Code.
You can do this by pressing `Ctrl + Shift + P` and typing `MCP: List Servers`, or you can create a `.vscode/mcp.json` file inside your repository.

Once you have done it, toggle Agent mode (located by the Copilot Chat text input) and the server will start.

:::note
The `mcp` key is not needed in the `.vscode/mcp.json` file.
Also note that you can change the host of the Console instance to your custom installation
The `mcp` key is not needed in the `.vscode/mcp.json` file.
Also note that you can change the host of the Console instance to your custom installation.
:::

This is the configuration if you are using miactl (a)
This is the configuration if you are using User Authentication with OAuth2 and Dynamic Client Registration.

```json
{
Expand All @@ -63,7 +50,7 @@ This is the configuration if you are using miactl (a)
}
```

This is the configuration if you are using Service Account (b)
This is the configuration if you are using a predefined Service Account.

```json
{
Expand Down Expand Up @@ -110,11 +97,9 @@ This is the configuration if you are using Service Account (b)
```

:::tip
If you want to use User-based authentication with [`miactl`][miactl] you have to omit from the env object:

- `MIA_PLATFORM_CLIENT_ID`
- `MIA_PLATFORM_CLIENT_SECRET`
If both the environment variables `MIA_PLATFORM_CLIENT_ID` and `MIA_PLATFORM_CLIENT_SECRET` are included, you will be asked to authenticate with your credentials. In this case, make sure you open the web page that Visual Studio Code will prompt you to open.

If you have issues to authenticate because of an `invalid_client` error, please try to remove the DCR clients registrated using the `Authentication: Remove Dynamic Authentication Providers` option from the application menu.
:::

More about using MCP server tools in [VS Code's agent mode documentation].
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default tseslint.config(
ignoreCase: true,
ignoreDeclarationSort: false,
ignoreMemberSort: false,
memberSyntaxSortOrder: [ 'none', 'all', 'single', 'multiple' ],
memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple'],
allowSeparatedGroups: true,
},
],
Expand Down
30 changes: 29 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"homepage": "https://github.com/mia-platform/console-mcp-server#readme",
"dependencies": {
"@fastify/formbody": "^8.0.2",
"@mia-platform/console-types": "^0.39.4",
"@modelcontextprotocol/sdk": "^1.19.1",
"commander": "^14.0.1",
Expand All @@ -52,4 +53,4 @@
"typescript": "^5.9.3",
"typescript-eslint": "^8.45.0"
}
}
}
6 changes: 3 additions & 3 deletions src/apis/http-client/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ suite('http client test suite without authentication', () => {
t.assert.deepEqual(result, { message: 'test' })
})


test('set custom headers, custom accept', async (t) => {
const customHeadersClient = new HTTPClient(mockedEndpoint, '', '', {
'custom-header': 'customValue',
Expand Down Expand Up @@ -199,6 +198,7 @@ suite('http client test suite with authentication', () => {
let agent: MockAgent
beforeEach(() => {
agent = new MockAgent()
agent.disableNetConnect()
setGlobalDispatcher(agent)
agent.get(mockedEndpoint).intercept({
path: '/api/m2m/oauth/token',
Expand Down Expand Up @@ -333,7 +333,7 @@ suite('http client test suite with authentication', () => {
test('set custom headers, don\'t override fixed ones', async (t) => {
const client = new HTTPClient(mockedEndpoint, clientID, clientSecret, {
'custom-header': 'customValue',
Authorization: 'custom authorization',
Authorization: 'Bearer token-coming-from-original-request',
Accept: 'custom accept value',
'User-Agent': 'custom user agent',
})
Expand All @@ -342,7 +342,7 @@ suite('http client test suite with authentication', () => {
path: testPath,
headers: {
'custom-header': 'customValue',
Authorization: `Bearer ${accessToken}`,
Authorization: 'Bearer token-coming-from-original-request',
Accept: 'custom accept value',
'User-Agent': `${name}/${version}`,
},
Expand Down
Loading