-
Notifications
You must be signed in to change notification settings - Fork 25
#1045: ✨ Complete MCP Server Scaffold #1065
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
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
ed32d3d
✨ #1045: Complete MCP Server Scaffold
mistryrn 04a2e9f
📝 Update MCP Server README
mistryrn 6ebb16c
✅ Add Unit Tests for `validateArrangerConnection`
mistryrn 38b9205
✅ Add Unit Tests for `createArrangerMcpConfig`
mistryrn a3a24d0
✅ Add Integration Tests for MCP Server
mistryrn 9f26b7f
💡 Update comments in MCP Server integration tests for clarity
mistryrn 0b5f1ac
Merge branch 'main' into feat/1045-complete-mcp-server-scaffold
mistryrn c1de31e
Merge branch 'main' into feat/1045-complete-mcp-server-scaffold
mistryrn 1aa3918
✅ Update MCP Server Types and Tests
mistryrn 1bd48fd
🔥 Remove `pnpm-lock.yaml`
mistryrn 3d1503a
💚 Move MCP Server `tsx` from `devDependencies` to `dependencies`
mistryrn 7d22617
👷 Add Dockerfile target for `mcp-server`
mistryrn 9b88e20
Merge branch 'main' into feat/1045-complete-mcp-server-scaffold
mistryrn ab2ca15
✏️ Fix typos in MCP Server README and package.json
mistryrn fab720c
🎨 Use alias for Zod import in MCP Tools
mistryrn 89d63fc
🎨 Improve graceful shutdown of MCP Server Express app
mistryrn 1656f9e
♻️ Refactor MCP Server Tools for Consistency
mistryrn c644d5d
Merge branch 'main' into feat/1045-complete-mcp-server-scaffold
mistryrn 863a022
♻️ PR Feedback: Refactor MCP Server "List Catalogs" Tool
mistryrn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| ARRANGER_BASE_URL=http://localhost:5050 | ||
| ARRANGER_CATALOGUES=server | ||
| ARRANGER_REQUEST_TIMEOUT_MS=10_000 | ||
|
|
||
| MCP_HOST=0.0.0.0 | ||
| MCP_PORT=3100 | ||
| MCP_PATH=/mcp | ||
|
|
||
| LOG_LEVEL=info |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,68 +1,153 @@ | ||
| # Arranger MCP Server Foundation | ||
| # Arranger MCP Server | ||
|
|
||
| This app is the starting point for an MCP server that learns how to talk to Arranger by consuming Arranger's introspection endpoints. | ||
| This app is an MCP server that learns how to talk to Arranger by consuming Arranger's introspection endpoints. | ||
|
|
||
| The current scaffold does not implement a full MCP transport or SDK binding yet. Instead, it defines: | ||
| The current scaffold implements the Streamable HTTP MCP transport using **v1.x** of the official [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x). | ||
|
|
||
| - how to read Arranger introspection | ||
| - how to model that information as MCP-friendly resources | ||
| - which MCP tools are natural to expose first | ||
| ## Folder Structure | ||
|
|
||
| ## Why this exists | ||
| ```text | ||
| src/ | ||
| ├── arranger/ | ||
| │ ├── client.ts # fetches Arranger introspection endpoints | ||
| │ ├── types.ts # response types for introspection payloads | ||
| │ └── validation.ts # validates the connection to Arranger | ||
| ├── http/ | ||
| │ └── app.ts # MCP express app with Streamable HTTP transport | ||
| ├── mcp/ | ||
| │ ├── resources.ts # registers MCP resources | ||
| │ └── tools.ts # registers MCP tools | ||
| ├── utils/ | ||
| │ ├── config.ts # env/config parsing | ||
| │ ├── inMemoryEventStore.ts # in-memory storage util for dev | ||
| │ └── logger.ts # pino logger wrapper | ||
| ├── index.ts # entrypoint for the application | ||
| └── server.ts # creates the MCP server | ||
| ``` | ||
|
|
||
| The intended flow is: | ||
| ## Quick Start | ||
|
|
||
| 1. call Arranger's `/introspection` | ||
| 2. call Arranger's `/introspection/sqon` | ||
| 3. call Arranger's `/introspection/:catalogId` | ||
| 4. expose those results to MCP clients as resources and tool-backed lookups | ||
| 1. Install dependencies: | ||
|
|
||
| ## Tools vs skills | ||
| ```bash | ||
| # from project root | ||
| npm ci | ||
| ``` | ||
|
|
||
| In this context: | ||
| 2. Configure environment variables: | ||
|
|
||
| - **tools** are callable operations an MCP client can invoke, such as "list catalogs" or "get SQON schema" | ||
| - **resources** are readable documents the MCP client can fetch, such as the server introspection payload or a catalog field listing | ||
| - **skills** are not part of the MCP standard itself; they are higher-level agent behaviors or authored instructions layered on top of tools/resources | ||
| > [!NOTE] | ||
| > See [Configuration](#configuration) for more details. | ||
|
|
||
| For this scaffold, the important MCP building blocks are tools and resources. | ||
| ```bash | ||
| # from apps/mcp-server | ||
| cp .env.schema .env | ||
| ``` | ||
|
|
||
| ## Folder layout | ||
| 3. Build Arranger modules: | ||
|
|
||
| ```text | ||
| src/ | ||
| arranger/ | ||
| client.ts # fetches Arranger introspection endpoints | ||
| types.ts # response types for introspection payloads | ||
| mcp/ | ||
| resources.ts # MCP-facing resource definitions backed by introspection | ||
| tools.ts # MCP-facing tool definitions backed by introspection | ||
| types.ts # simple MCP-ish types for the scaffold | ||
| config.ts # env/config parsing for the future MCP server | ||
| index.ts # composition entrypoint for the scaffold | ||
| ```bash | ||
| # from project root | ||
| npm run modules:build | ||
| ``` | ||
|
|
||
| ## Intended first MCP features | ||
| 4. (Optional) Ensure Elasticsearch and Arranger Server are running. | ||
|
|
||
| - `list_catalogs` | ||
| - `get_sqon_schema` | ||
| - `get_catalog_fields` | ||
| > [!NOTE] | ||
| > This is only necessary if you are developing against a local Arranger Server. See [Testing](#testing) for more details. | ||
|
|
||
| Those all map directly to already-implemented Arranger introspection endpoints. | ||
| ```bash | ||
| # from project root | ||
| make start-es | ||
| ES_INDEX=file_centric DOCUMENT_TYPE=file CONFIGS_PATH=$(pwd)/docker/server npm run dev:server | ||
| ``` | ||
|
|
||
| ## Not implemented yet | ||
| 5. Start the MCP Server: | ||
|
|
||
| - actual MCP SDK bootstrap | ||
| - stdin/stdout server transport | ||
| - authentication | ||
| - query execution tools | ||
| - SQON generation helpers beyond introspection exposure | ||
| ```bash | ||
| # from project root | ||
| npm run mcp-server:dev | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| Configuration of this application is done by providing [environment variables](#environment-variables) to the application at run time. | ||
|
|
||
| > [!WARNING] | ||
| > If **required** environment variables are not available or misconfigured at run time, the application will shut down immediately. | ||
|
|
||
| An example environment variables file is located at [`.env.schema`](./.env.schema). This example file lists all available configuration variables and is prepopulated with default values that should work to run the application locally. You can copy the contents of this file to populate a `.env`: | ||
|
|
||
| ```bash | ||
| # from apps/mcp-server | ||
| cp .env.schema .env | ||
| ``` | ||
|
|
||
| ### Environment Variables | ||
|
|
||
| | Name | Description | Type | Required | Default | | ||
| | -------------------------- | ----------------------------------------------------------------------- | -------- | ------------ | ----------------------- | | ||
| | `ARRANGER_BASE_URL` | URL for the Arranger Server | `string` | **Required** | `http://localhost:5050` | | ||
| | `ARRANGER_CATALOGUES` | Comma-separated list of Arranger catalogues to expose to the MCP Server | `string` | **Required** | `server` | | ||
| | `ARRANGER_REQUEST_TIMEOUT_MS` | Timeout for requests to Arranger | `number` | Optional | `10_000` | | ||
| | `MCP_HOST` | Host URL for the MCP server | `string` | Optional | `0.0.0.0` | | ||
| | `MCP_PORT` | Port the MCP Server will listen for requests on | `number` | Optional | `3100` | | ||
| | `MCP_PATH` | Endpoint for the MCP Streamable HTTP transport | `string` | Optional | `/mcp` | | ||
| | `LOG_LEVEL` | Pino [log level](https://getpino.io/#/docs/api?id=level-1) | `string` | Optional | `info` | | ||
|
|
||
| ## Testing | ||
|
|
||
| ### Local Arranger | ||
|
|
||
| ## Suggested next step | ||
| To test the MCP Server against a **local** instance of Arranger Server: | ||
|
|
||
| When you're ready to implement the actual MCP server, keep this app focused on: | ||
| 1. Confirm your [`apps/mcp-server/.env`](.env) configuration aligns with your local Arranger server. | ||
|
|
||
| - fetching and caching Arranger introspection | ||
| - exposing catalog and SQON metadata to MCP clients | ||
| 2. Ensure ES and Arranger Server are running: | ||
|
|
||
| Then add query execution tools only after the metadata contract feels stable. | ||
| ```bash | ||
| # from project root | ||
|
|
||
| # start ES (note: you may need to seed ES with `make seed-es` after if this is your first time) | ||
| make start-es | ||
|
|
||
| # start Arranger Server (config may vary) | ||
| ES_INDEX=file_centric DOCUMENT_TYPE=file CONFIGS_PATH=$(pwd)/docker/server npm run dev:server | ||
| ``` | ||
|
|
||
| 3. Start the MCP Server: | ||
|
|
||
| ```bash | ||
| # from project root | ||
| npm run mcp-server:dev | ||
| ``` | ||
|
|
||
| 4. Start the [MCP Inspector](https://github.com/modelcontextprotocol/inspector): | ||
|
|
||
| ```bash | ||
| # from project root | ||
| npm run mcp-server:inspect | ||
| ``` | ||
|
|
||
| 5. You can then open the MCP Inspector URL in your web browser (`http://localhost:6274/?MCP_PROXY_AUTH_TOKEN={AUTH_TOKEN}`), connect to the MCP Server via Streamable HTTP, and test the Resources and Tools. | ||
|
|
||
| ### Remote Arranger | ||
|
|
||
| To test against a **remote** instance of Arranger Server: | ||
|
|
||
| 1. Update the `ARRANGER_BASE_URL` and `ARRANGER_CATALOGUES` in your MCP Server `.env` file to point to and reflect the state of your remote Arranger. | ||
| 2. Follow steps 3-5 of the [**local**](#local-arranger) testing instructions. | ||
|
|
||
| ### LM Studio | ||
|
|
||
| To test with **LM Studio** instead of MCP Inspector: | ||
|
|
||
| - Follow the LM Studio instructions to add an MCP server configuration: https://lmstudio.ai/docs/app/mcp | ||
| - Provide the config JSON in [`apps/mcp-server/mcp-inspector.json`](./mcp-inspector.json) | ||
|
|
||
| ## Not Implemented Yet | ||
|
|
||
| - stdin/stdout server transport | ||
| - authentication | ||
| - query execution tools | ||
| - SQON generation helpers beyond introspection exposure |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "mcpServers": { | ||
| "mcp-server": { | ||
| "type": "streamable-http", | ||
| "url": "http://127.0.0.1:3100/mcp" | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,45 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/package.json", | ||
| "name": "@overture-stack/arranger-mcp-server", | ||
| "description": "Arranger MCP Server", | ||
| "version": "0.0.0-dev", | ||
| "homepage": "https://github.com/overture-stack/arranger#readme", | ||
| "bugs": { | ||
| "url": "https://github.com/overture-stack/arranger/issues" | ||
| }, | ||
| "main": "src/index.ts", | ||
| "types": "src/index.ts", | ||
| "repository": { | ||
| "directory": "apps/mcp-server", | ||
| "type": "git", | ||
| "url": "git+https://github.com/overture-stack/arranger.git" | ||
| }, | ||
| "private": true, | ||
| "scripts": { | ||
| "dev": "NODE_ENV=development tsx watch --include './src/**/*' ./src/index.ts", | ||
| "start": "tsx ./src/index.ts", | ||
| "test": "tsx --test --experimental-test-module-mocks ./src/**/*.test.ts", | ||
| "inspect": "npx @modelcontextprotocol/inspector --config ./mcp-inspector.json --server mcp-server" | ||
| }, | ||
| "dependencies": { | ||
| "@modelcontextprotocol/sdk": "^1.29.0", | ||
| "cors": "^2.8.6", | ||
| "dotenv": "^16.6.1", | ||
| "express": "^4.21.2", | ||
| "pino": "^10.3.1", | ||
| "pino-pretty": "^13.1.3", | ||
| "tsx": "^4.21.0", | ||
| "zod": "^3.25.76" | ||
| }, | ||
| "devDependencies": { | ||
| "@tsconfig/node22": "^22.0.5", | ||
| "@types/cors": "^2.8.12", | ||
| "@types/express": "^4.17.14", | ||
| "@types/node": "^25.6.2", | ||
| "typescript": "^5.8.3" | ||
| }, | ||
| "imports": { | ||
| "#*": "./src/*" | ||
| }, | ||
| "type": "module" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.