@ama-mcp/sdk 0.0.0 → 14.2.0-prerelease.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/README.md +124 -0
- package/package.json +141 -2
- package/resources/INSTRUCTIONS.md +40 -0
- package/src/cli.d.ts +3 -0
- package/src/cli.d.ts.map +1 -0
- package/src/cli.js +76 -0
- package/src/cli.js.map +1 -0
- package/src/helpers/context.d.ts +21 -0
- package/src/helpers/context.d.ts.map +1 -0
- package/src/helpers/context.js +56 -0
- package/src/helpers/context.js.map +1 -0
- package/src/helpers/utils.d.ts +22 -0
- package/src/helpers/utils.d.ts.map +1 -0
- package/src/helpers/utils.js +55 -0
- package/src/helpers/utils.js.map +1 -0
- package/src/server/mcp-server.d.ts +42 -0
- package/src/server/mcp-server.d.ts.map +1 -0
- package/src/server/mcp-server.js +168 -0
- package/src/server/mcp-server.js.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Copyright Amadeus SAS
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
4
|
+
are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
7
|
+
list of conditions and the following disclaimer.
|
|
8
|
+
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation and/or
|
|
11
|
+
other materials provided with the distribution.
|
|
12
|
+
|
|
13
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
may be used to endorse or promote products derived from this software without
|
|
15
|
+
specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
21
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
22
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
24
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
26
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# @ama-mcp/sdk
|
|
2
|
+
|
|
3
|
+
MCP module to expose `SDK_CONTEXT.md` from installed packages to AI assistants.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
When SDKs are generated using [@ama-sdk/schematics](https://www.npmjs.com/package/@ama-sdk/schematics), they can include an `SDK_CONTEXT.md` file that describes:
|
|
8
|
+
- Available API domains and operations
|
|
9
|
+
- Models used by each domain
|
|
10
|
+
- Guidelines for AI tools to avoid hallucinations
|
|
11
|
+
|
|
12
|
+
This MCP module automatically discovers and loads these context files from installed packages using Node.js's module resolution, then exposes them to AI assistants.
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
### VS Code `.vscode/mcp.json`
|
|
17
|
+
|
|
18
|
+
Configure SDK packages directly in your `.vscode/mcp.json`:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"servers": {
|
|
23
|
+
"sdk-context": {
|
|
24
|
+
"command": "npx",
|
|
25
|
+
"args": ["ama-mcp-sdk", "--packages", "@my-scope/my-sdk-package", "@other-scope/other-sdk"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### CLI (for mcp.json)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Specify packages with --packages flag
|
|
37
|
+
ama-mcp-sdk --packages @my-scope/my-sdk @other-scope/other-sdk
|
|
38
|
+
|
|
39
|
+
# Show help
|
|
40
|
+
ama-mcp-sdk --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Programmatic (in custom MCP server)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { registerSdkContextToolAndResources } from '@ama-mcp/sdk';
|
|
47
|
+
|
|
48
|
+
// With explicit packages
|
|
49
|
+
await registerSdkContextToolAndResources(server, {
|
|
50
|
+
sdkPackages: ['@my-scope/my-sdk']
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Or reads from package.json sdkContext.packages automatically
|
|
54
|
+
await registerSdkContextToolAndResources(server);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Available Tool
|
|
58
|
+
|
|
59
|
+
**`get_sdk_context`** - Retrieve SDK context for configured packages
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
// List all configured SDKs with context
|
|
63
|
+
get_sdk_context()
|
|
64
|
+
|
|
65
|
+
// Get context for specific package
|
|
66
|
+
get_sdk_context({ packageName: "@my-scope/my-sdk-package" })
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Available Resources
|
|
70
|
+
|
|
71
|
+
**`sdk-context://instructions`** - Usage guidelines for AI assistants
|
|
72
|
+
|
|
73
|
+
This resource provides instructions on how to use SDK context effectively to avoid hallucinations when implementing features. AI assistants should read this resource before using the `get_sdk_context` tool.
|
|
74
|
+
|
|
75
|
+
**`sdk-context://<package-name>`** - SDK context for each configured package
|
|
76
|
+
|
|
77
|
+
Each configured SDK package that has an `SDK_CONTEXT.md` file is exposed as a resource.
|
|
78
|
+
|
|
79
|
+
## How It Works
|
|
80
|
+
|
|
81
|
+
1. Reads `sdkContext.packages` from project's `package.json` or uses CLI arguments
|
|
82
|
+
2. Uses Node.js `require.resolve()` to automatically locate packages
|
|
83
|
+
3. Loads `SDK_CONTEXT.md` from each resolved package
|
|
84
|
+
4. Registers each as an MCP resource
|
|
85
|
+
5. Provides a tool for AI assistants to query SDK information
|
|
86
|
+
|
|
87
|
+
## Package Resolution
|
|
88
|
+
|
|
89
|
+
The SDK automatically discovers packages using Node.js's `require.resolve()`. This means:
|
|
90
|
+
|
|
91
|
+
- **No manual path configuration needed** - packages are found automatically
|
|
92
|
+
- **Works with workspaces** - supports npm/yarn/pnpm workspace configurations
|
|
93
|
+
- **Flexible installation** - works with local, global, or custom module paths
|
|
94
|
+
- **Error handling** - clear error messages when packages aren't found
|
|
95
|
+
|
|
96
|
+
If a package isn't found, ensure:
|
|
97
|
+
1. The package is installed (`npm install <package-name>`)
|
|
98
|
+
2. The package name is spelled correctly
|
|
99
|
+
3. The package has an `SDK_CONTEXT.md` file in its root
|
|
100
|
+
|
|
101
|
+
**Security**: The system validates package names to prevent path traversal attacks and only accepts valid npm package name patterns.
|
|
102
|
+
|
|
103
|
+
## Troubleshooting
|
|
104
|
+
|
|
105
|
+
### Package Not Found
|
|
106
|
+
```
|
|
107
|
+
Package "@my-scope/my-sdk" not found. Is it installed?
|
|
108
|
+
```
|
|
109
|
+
**Solution**: Install the package or verify the name in your configuration.
|
|
110
|
+
|
|
111
|
+
### No SDK_CONTEXT.md Found
|
|
112
|
+
```
|
|
113
|
+
No SDK_CONTEXT.md found for @my-scope/my-sdk
|
|
114
|
+
```
|
|
115
|
+
**Solution**: Generate the context file using the command below.
|
|
116
|
+
|
|
117
|
+
## Generating SDK Context
|
|
118
|
+
|
|
119
|
+
SDK maintainers can generate `SDK_CONTEXT.md` using:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cd /path/to/sdk-project
|
|
123
|
+
npx amasdk-update-sdk-context --interactive
|
|
124
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,146 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ama-mcp/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.2.0-prerelease.19",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
|
-
}
|
|
6
|
+
},
|
|
7
|
+
"description": "Experimental package -- MCP module to expose SDK_CONTEXT.md from installed packages to AI assistants",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"mcp",
|
|
10
|
+
"sdk",
|
|
11
|
+
"ai-context",
|
|
12
|
+
"otter-module"
|
|
13
|
+
],
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"bin": {
|
|
16
|
+
"ama-mcp-sdk": "./src/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
"./package.json": {
|
|
20
|
+
"default": "./package.json"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"nx": "nx",
|
|
25
|
+
"ng": "yarn nx",
|
|
26
|
+
"build": "yarn nx build ama-mcp-sdk",
|
|
27
|
+
"compile": "tsc -b ./tsconfig.build.json && yarn cpy package.json dist && patch-package-json-main",
|
|
28
|
+
"copy:resources": "yarn cpy resources dist"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@ama-mcp/core": "~14.2.0-prerelease.19",
|
|
32
|
+
"@modelcontextprotocol/sdk": "~1.27.0",
|
|
33
|
+
"@o3r/telemetry": "~14.2.0-prerelease.19",
|
|
34
|
+
"commander": "^14.0.0",
|
|
35
|
+
"tslib": "^2.6.2",
|
|
36
|
+
"zod": "~4.3.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@ama-mcp/core": "~14.2.0-prerelease.19",
|
|
40
|
+
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
|
|
41
|
+
"@modelcontextprotocol/sdk": "~1.27.0",
|
|
42
|
+
"@nx/eslint": "~22.6.0",
|
|
43
|
+
"@nx/eslint-plugin": "~22.6.0",
|
|
44
|
+
"@nx/jest": "~22.6.0",
|
|
45
|
+
"@nx/js": "~22.6.0",
|
|
46
|
+
"@o3r/build-helpers": "^14.2.0-prerelease.19",
|
|
47
|
+
"@o3r/eslint-config": "^14.2.0-prerelease.19",
|
|
48
|
+
"@o3r/eslint-plugin": "^14.2.0-prerelease.19",
|
|
49
|
+
"@o3r/test-helpers": "^14.2.0-prerelease.19",
|
|
50
|
+
"@stylistic/eslint-plugin": "~5.10.0",
|
|
51
|
+
"@types/jest": "~30.0.0",
|
|
52
|
+
"@types/node": "~24.12.0",
|
|
53
|
+
"@typescript-eslint/parser": "~8.57.0",
|
|
54
|
+
"cpy-cli": "^6.0.0",
|
|
55
|
+
"eslint": "~9.39.0",
|
|
56
|
+
"eslint-import-resolver-node": "~0.3.9",
|
|
57
|
+
"eslint-import-resolver-typescript": "~4.4.0",
|
|
58
|
+
"eslint-plugin-import": "~2.32.0",
|
|
59
|
+
"eslint-plugin-import-newlines": "~1.4.0",
|
|
60
|
+
"eslint-plugin-jest": "~29.15.0",
|
|
61
|
+
"eslint-plugin-jsdoc": "~61.7.0",
|
|
62
|
+
"eslint-plugin-prefer-arrow": "~1.2.3",
|
|
63
|
+
"eslint-plugin-unicorn": "~62.0.0",
|
|
64
|
+
"eslint-plugin-unused-imports": "~4.4.0",
|
|
65
|
+
"globals": "^16.0.0",
|
|
66
|
+
"jest": "~30.3.0",
|
|
67
|
+
"jest-junit": "~16.0.0",
|
|
68
|
+
"jsonc-eslint-parser": "~2.4.0",
|
|
69
|
+
"ts-jest": "~29.4.0",
|
|
70
|
+
"typescript": "~5.9.2",
|
|
71
|
+
"typescript-eslint": "~8.57.0",
|
|
72
|
+
"zod": "~4.3.0"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": "^22.17.0 || ^24.0.0"
|
|
76
|
+
},
|
|
77
|
+
"contributors": [
|
|
78
|
+
{
|
|
79
|
+
"name": "Yannick Adam",
|
|
80
|
+
"url": "https://github.com/yannickadam",
|
|
81
|
+
"email": "yannickadam@users.noreply.github.com"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "Kilian Panot",
|
|
85
|
+
"url": "https://github.com/kpanot",
|
|
86
|
+
"email": "kpanot@users.noreply.github.com"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "Jeremy Bourgeois",
|
|
90
|
+
"url": "https://github.com/jbourgeois-1A",
|
|
91
|
+
"email": "jbourgeois-1A@users.noreply.github.com"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "Pierre Henri Ginoux",
|
|
95
|
+
"url": "https://github.com/pginoux-1A",
|
|
96
|
+
"email": "pginoux-1A@users.noreply.github.com"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "Mircea Vasile Rednic",
|
|
100
|
+
"url": "https://github.com/mrednic-1A",
|
|
101
|
+
"email": "mrednic-1A@users.noreply.github.com"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "Stephane Dalle",
|
|
105
|
+
"url": "https://github.com/sdalle-1A",
|
|
106
|
+
"email": "sdalle-1A@users.noreply.github.com"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "Nicolas Hoffmann",
|
|
110
|
+
"url": "https://github.com/nhoffmann-1A",
|
|
111
|
+
"email": "nhoffmann-1A@users.noreply.github.com"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "Victor Scaiceanu",
|
|
115
|
+
"url": "https://github.com/vscaiceanu-1a",
|
|
116
|
+
"email": "vscaiceanu-1A@users.noreply.github.com"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "Florian Paul",
|
|
120
|
+
"url": "https://github.com/fpaul-1A",
|
|
121
|
+
"email": "fpaul-1A@users.noreply.github.com"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"name": "Corinne Paulve",
|
|
125
|
+
"url": "https://github.com/cpaulve-1A",
|
|
126
|
+
"email": "cpaulve-1A@users.noreply.github.com"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"name": "Matthieu Crouzet",
|
|
130
|
+
"url": "https://github.com/matthieu-crouzet",
|
|
131
|
+
"email": "matthieu-crouzet@users.noreply.github.com"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"name": "Salome Do",
|
|
135
|
+
"url": "https://github.com/sdo-1A",
|
|
136
|
+
"email": "sdo-1A@users.noreply.github.com"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"bugs": "https://github.com/AmadeusITGroup/otter/issues",
|
|
140
|
+
"repository": {
|
|
141
|
+
"type": "git",
|
|
142
|
+
"url": "git+https://github.com/AmadeusITGroup/otter.git"
|
|
143
|
+
},
|
|
144
|
+
"license": "BSD-3-Clause",
|
|
145
|
+
"homepage": "https://amadeusitgroup.github.io/otter/"
|
|
7
146
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# SDK Context Usage Instructions
|
|
2
|
+
|
|
3
|
+
When implementing features that use installed SDKs, use the `get_sdk_context` tool as your primary source of truth. The SDK context provides a structured methodology for understanding available operations, models, and their organization.
|
|
4
|
+
|
|
5
|
+
> **Note**: The SDKs available through this MCP server are those explicitly configured in the server launch parameters (via `--packages` arguments or `sdkContext.packages` in `package.json`). Only these SDKs will have context available through the `get_sdk_context` tool.
|
|
6
|
+
|
|
7
|
+
## Core Principle
|
|
8
|
+
|
|
9
|
+
**Let the SDK context guide your implementation.** The context document describes the SDK's structure, available operations, and models. Base your responses on what you discover in the context rather than making assumptions.
|
|
10
|
+
|
|
11
|
+
## Using the SDK Context
|
|
12
|
+
|
|
13
|
+
1. **Query available SDK contexts** using `get_sdk_context` without arguments to discover configured SDKs
|
|
14
|
+
2. **Retrieve the relevant SDK context** by calling `get_sdk_context` with the package name
|
|
15
|
+
3. **Study the context's structure and methodology** - each SDK context describes how its operations and models are organized
|
|
16
|
+
4. **Follow the patterns provided** - use the exact operation IDs, model imports, and domain organization as documented in the context
|
|
17
|
+
|
|
18
|
+
## Fallback Discovery
|
|
19
|
+
|
|
20
|
+
If the SDK context is unavailable or incomplete for a specific operation:
|
|
21
|
+
|
|
22
|
+
- Search for OpenAPI/Swagger specification files (e.g., `openapi.yaml`, `swagger.json`, `spec.yaml`) in the project
|
|
23
|
+
- Browse the SDK's source files to discover available API classes and methods
|
|
24
|
+
- Check the SDK's `package.json` for entry points or documentation references
|
|
25
|
+
|
|
26
|
+
## Key Principles
|
|
27
|
+
|
|
28
|
+
- **Ground your responses in the context** - only use operations, models, and paths that exist in the SDK context or specification
|
|
29
|
+
- **Respect the SDK's organization** - follow the domain structure and naming conventions provided
|
|
30
|
+
- **Avoid assumptions** - if something is not documented in the context, verify its existence before using it
|
|
31
|
+
|
|
32
|
+
## Troubleshooting
|
|
33
|
+
|
|
34
|
+
### No SDK contexts found
|
|
35
|
+
|
|
36
|
+
Ensure the SDK packages are:
|
|
37
|
+
1. Listed in `package.json` under `sdkContext.packages`
|
|
38
|
+
2. Or provided via CLI arguments: `--packages @scope/sdk-name`
|
|
39
|
+
3. Installed in node_modules
|
|
40
|
+
4. Have `SDK_CONTEXT.md` generated (use `amasdk-update-sdk-context` in the SDK project)
|
package/src/cli.d.ts
ADDED
package/src/cli.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const core_1 = require("@ama-mcp/core");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const telemetry_1 = require("@o3r/telemetry");
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const utils_1 = require("./helpers/utils");
|
|
9
|
+
const mcp_server_1 = require("./server/mcp-server");
|
|
10
|
+
const run = async () => {
|
|
11
|
+
const logger = new core_1.MCPLogger('@ama-mcp/sdk');
|
|
12
|
+
/**
|
|
13
|
+
* Validate and filter package names, logging warnings for invalid ones
|
|
14
|
+
* @param packageNames Raw package names from CLI
|
|
15
|
+
* @returns Validated package names
|
|
16
|
+
*/
|
|
17
|
+
const validatePackages = (packageNames) => packageNames.filter((pkg) => {
|
|
18
|
+
const isValid = (0, utils_1.isValidPackageName)(pkg);
|
|
19
|
+
if (!isValid) {
|
|
20
|
+
logger.warn?.(`Invalid package name "${pkg}", skipping`);
|
|
21
|
+
}
|
|
22
|
+
return isValid;
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* CLI program configuration using Commander.js
|
|
26
|
+
*
|
|
27
|
+
* Sets up the command-line interface with options and help text for the SDK Context MCP server.
|
|
28
|
+
*/
|
|
29
|
+
const program = new commander_1.Command();
|
|
30
|
+
program
|
|
31
|
+
.name('ama-mcp-sdk')
|
|
32
|
+
.description('SDK Context MCP Server\n\nExposes SDK_CONTEXT.md from installed packages to AI assistants.')
|
|
33
|
+
.option('-p, --packages <packages...>', 'List of SDK package names to expose (required if not configured in package.json)')
|
|
34
|
+
.addHelpText('after', `
|
|
35
|
+
Examples:
|
|
36
|
+
ama-mcp-sdk --packages @my-scope/my-sdk @other-scope/other-sdk
|
|
37
|
+
|
|
38
|
+
VS Code mcp.json example:
|
|
39
|
+
{
|
|
40
|
+
"servers": {
|
|
41
|
+
"sdk-context": {
|
|
42
|
+
"command": "npx",
|
|
43
|
+
"args": ["ama-mcp-sdk", "--packages", "@my-scope/my-sdk", "@other-scope/other-sdk"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}`);
|
|
47
|
+
/**
|
|
48
|
+
* Parse CLI arguments and validate package names
|
|
49
|
+
*
|
|
50
|
+
* Extracts package names from command line arguments and validates them using
|
|
51
|
+
* the package name validation rules.
|
|
52
|
+
*/
|
|
53
|
+
const { packages: rawPackages } = program.parse().opts();
|
|
54
|
+
const packages = validatePackages(rawPackages || []);
|
|
55
|
+
/**
|
|
56
|
+
* Main entry point for the SDK Context MCP server
|
|
57
|
+
*
|
|
58
|
+
* Initializes and starts the MCP server with SDK context tools and resources.
|
|
59
|
+
* The server exposes SDK_CONTEXT.md files from configured packages to AI assistants.
|
|
60
|
+
* @returns Promise that resolves when the server is successfully started
|
|
61
|
+
*/
|
|
62
|
+
try {
|
|
63
|
+
const server = (0, mcp_server_1.createSdkContextServer)({
|
|
64
|
+
sdkPackages: packages.length > 0 ? packages : undefined,
|
|
65
|
+
logger
|
|
66
|
+
});
|
|
67
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
68
|
+
await server.connect(transport);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
logger.error?.('Failed to start SDK Context MCP server:', error);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
void (0, telemetry_1.createCliWithMetrics)(run, '@ama-sdk/cli')();
|
|
76
|
+
//# sourceMappingURL=cli.js.map
|
package/src/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";;;AAEA,wCAEuB;AACvB,wEAEmD;AACnD,8CAEwB;AACxB,yCAEmB;AACnB,2CAEyB;AACzB,oDAE6B;AAE7B,MAAM,GAAG,GAAG,KAAK,IAAmB,EAAE;IACpC,MAAM,MAAM,GAAG,IAAI,gBAAS,CAAC,cAAc,CAAC,CAAC;IAE7C;;;;OAIG;IACH,MAAM,gBAAgB,GAAG,CAAC,YAAsB,EAAY,EAAE,CAC5D,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,IAAA,0BAAkB,EAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,EAAE,CAAC,yBAAyB,GAAG,aAAa,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEL;;;;OAIG;IACH,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,WAAW,CAAC,4FAA4F,CAAC;SACzG,MAAM,CAAC,8BAA8B,EAAE,kFAAkF,CAAC;SAC1H,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;IAYtB,CAAC,CAAC;IAEJ;;;;;OAKG;IACH,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAErD;;;;;;OAMG;IACH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,mCAAsB,EAAC;YACpC,WAAW,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YACvD,MAAM;SACP,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,EAAE,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;QACjE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AACF,KAAK,IAAA,gCAAoB,EAAC,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Logger } from '@ama-mcp/core';
|
|
2
|
+
/**
|
|
3
|
+
* Information about a loaded SDK context
|
|
4
|
+
*/
|
|
5
|
+
export interface SdkContextInfo {
|
|
6
|
+
/** The npm package name */
|
|
7
|
+
packageName: string;
|
|
8
|
+
/** The content of the SDK_CONTEXT.md file */
|
|
9
|
+
content: string;
|
|
10
|
+
/** The resource URI for this context */
|
|
11
|
+
uri: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Load SDK contexts from explicitly configured packages
|
|
15
|
+
* @param sdkPackages List of package names to load
|
|
16
|
+
* @param contextFileName Name of the context file to load
|
|
17
|
+
* @param logger Optional logger for debug output
|
|
18
|
+
* @returns Array of loaded SDK context information
|
|
19
|
+
*/
|
|
20
|
+
export declare const loadSdkContexts: (sdkPackages: string[], contextFileName: string, logger?: Logger) => SdkContextInfo[];
|
|
21
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/helpers/context.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,MAAM,EACP,MAAM,eAAe,CAAC;AAMvB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;CACb;AA+CD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,EAAE,EAAE,iBAAiB,MAAM,EAAE,SAAS,MAAM,KAAG,cAAc,EAGvD,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadSdkContexts = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
/**
|
|
8
|
+
* Try to load SDK context for a single package using Node's module resolution
|
|
9
|
+
* @param packageName Package name to load
|
|
10
|
+
* @param contextFileName Name of the context file to load
|
|
11
|
+
* @param logger Optional logger for debug output
|
|
12
|
+
* @returns SDK context info or null if not found/invalid
|
|
13
|
+
*/
|
|
14
|
+
const tryLoadSdkContext = (packageName, contextFileName, logger) => {
|
|
15
|
+
if (!(0, utils_1.isValidPackageName)(packageName)) {
|
|
16
|
+
logger?.warn?.(`Skipping invalid package name: "${packageName}"`);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
let packagePath = null;
|
|
20
|
+
// Try to resolve using Node's module resolution
|
|
21
|
+
try {
|
|
22
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`, { paths: [process.cwd()] });
|
|
23
|
+
packagePath = (0, node_path_1.dirname)(packageJsonPath);
|
|
24
|
+
logger?.debug?.(`Resolved ${packageName} using require.resolve: ${packagePath}`);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
logger?.warn?.(`Package "${packageName}" not found. Is it installed?`);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const contextPath = (0, node_path_1.join)(packagePath, contextFileName);
|
|
31
|
+
if (!(0, node_fs_1.existsSync)(contextPath)) {
|
|
32
|
+
logger?.debug?.(`No SDK_CONTEXT.md found for ${packageName} at ${contextPath}`);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const content = (0, node_fs_1.readFileSync)(contextPath, 'utf8');
|
|
37
|
+
logger?.debug?.(`Loaded SDK context for ${packageName}`);
|
|
38
|
+
return { packageName, content, uri: (0, utils_1.generateUri)(packageName) };
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger?.error?.(`Failed to read SDK context for ${packageName}:`, error);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Load SDK contexts from explicitly configured packages
|
|
47
|
+
* @param sdkPackages List of package names to load
|
|
48
|
+
* @param contextFileName Name of the context file to load
|
|
49
|
+
* @param logger Optional logger for debug output
|
|
50
|
+
* @returns Array of loaded SDK context information
|
|
51
|
+
*/
|
|
52
|
+
const loadSdkContexts = (sdkPackages, contextFileName, logger) => sdkPackages
|
|
53
|
+
.map((pkg) => tryLoadSdkContext(pkg, contextFileName, logger))
|
|
54
|
+
.filter((ctx) => ctx !== null);
|
|
55
|
+
exports.loadSdkContexts = loadSdkContexts;
|
|
56
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/helpers/context.ts"],"names":[],"mappings":";;;AAAA,qCAGiB;AACjB,yCAGmB;AAInB,mCAGiB;AAcjB;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,CACxB,WAAmB,EACnB,eAAuB,EACvB,MAAe,EACQ,EAAE;IACzB,IAAI,CAAC,IAAA,0BAAkB,EAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,IAAI,EAAE,CAAC,mCAAmC,WAAW,GAAG,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,WAAW,GAAkB,IAAI,CAAC;IAEtC,gDAAgD;IAChD,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,WAAW,eAAe,EAAE,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnG,WAAW,GAAG,IAAA,mBAAO,EAAC,eAAe,CAAC,CAAC;QACvC,MAAM,EAAE,KAAK,EAAE,CAAC,YAAY,WAAW,2BAA2B,WAAW,EAAE,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,EAAE,IAAI,EAAE,CAAC,YAAY,WAAW,+BAA+B,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IACvD,IAAI,CAAC,IAAA,oBAAU,EAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,EAAE,KAAK,EAAE,CAAC,+BAA+B,WAAW,OAAO,WAAW,EAAE,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,EAAE,KAAK,EAAE,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,IAAA,mBAAW,EAAC,WAAW,CAAC,EAAE,CAAC;IACjE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,KAAK,EAAE,CAAC,kCAAkC,WAAW,GAAG,EAAE,KAAK,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,eAAe,GAAG,CAAC,WAAqB,EAAE,eAAuB,EAAE,MAAe,EAAoB,EAAE,CACnH,WAAW;KACR,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;KAC7D,MAAM,CAAC,CAAC,GAAG,EAAyB,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;AAH7C,QAAA,eAAe,mBAG8B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Logger } from '@ama-mcp/core';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that a package name is safe and follows npm naming conventions.
|
|
4
|
+
* Prevents path traversal attacks and ensures the name is a valid npm package.
|
|
5
|
+
* @param packageName The package name to validate
|
|
6
|
+
* @returns true if the package name is valid and safe
|
|
7
|
+
*/
|
|
8
|
+
export declare const isValidPackageName: (packageName: string) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Load SDK packages list from package.json
|
|
11
|
+
* @param projectPath Path to project root
|
|
12
|
+
* @param logger Optional logger for debug output
|
|
13
|
+
* @returns Array of package names configured in sdkContext.packages
|
|
14
|
+
*/
|
|
15
|
+
export declare const loadSdkPackagesFromPackageJson: (projectPath: string, logger?: Logger) => string[];
|
|
16
|
+
/**
|
|
17
|
+
* Generates a safe URI from a package name
|
|
18
|
+
* @param packageName The npm package name
|
|
19
|
+
* @returns A URI-safe identifier
|
|
20
|
+
*/
|
|
21
|
+
export declare const generateUri: (packageName: string) => string;
|
|
22
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/helpers/utils.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,MAAM,EACP,MAAM,eAAe,CAAC;AAQvB;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,KAAG,OAGR,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAAI,aAAa,MAAM,EAAE,SAAS,MAAM,KAAG,MAAM,EAmB3F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,aAAa,MAAM,KAAG,MACsB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateUri = exports.loadSdkPackagesFromPackageJson = exports.isValidPackageName = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
/** URI prefix for SDK context resources */
|
|
7
|
+
const RESOURCE_URI_PREFIX = 'sdk-context';
|
|
8
|
+
/** Pattern for valid npm package names (scoped and unscoped) - must be lowercase per npm spec */
|
|
9
|
+
const VALID_PACKAGE_NAME_PATTERN = /^(@[a-z\d][\w.-]*\/)?[a-z\d][\w.-]*$/;
|
|
10
|
+
/**
|
|
11
|
+
* Validates that a package name is safe and follows npm naming conventions.
|
|
12
|
+
* Prevents path traversal attacks and ensures the name is a valid npm package.
|
|
13
|
+
* @param packageName The package name to validate
|
|
14
|
+
* @returns true if the package name is valid and safe
|
|
15
|
+
*/
|
|
16
|
+
const isValidPackageName = (packageName) => Boolean(packageName)
|
|
17
|
+
&& typeof packageName === 'string'
|
|
18
|
+
&& VALID_PACKAGE_NAME_PATTERN.test(packageName);
|
|
19
|
+
exports.isValidPackageName = isValidPackageName;
|
|
20
|
+
/**
|
|
21
|
+
* Load SDK packages list from package.json
|
|
22
|
+
* @param projectPath Path to project root
|
|
23
|
+
* @param logger Optional logger for debug output
|
|
24
|
+
* @returns Array of package names configured in sdkContext.packages
|
|
25
|
+
*/
|
|
26
|
+
const loadSdkPackagesFromPackageJson = (projectPath, logger) => {
|
|
27
|
+
const packageJsonPath = (0, node_path_1.join)(projectPath, 'package.json');
|
|
28
|
+
if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
29
|
+
logger?.debug?.(`No package.json found at ${packageJsonPath}`);
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf8'));
|
|
34
|
+
return (packageJson.sdkContext?.packages ?? []).filter((pkg) => {
|
|
35
|
+
const valid = (0, exports.isValidPackageName)(pkg);
|
|
36
|
+
if (!valid) {
|
|
37
|
+
logger?.warn?.(`Invalid package name in sdkContext.packages: "${pkg}", skipping`);
|
|
38
|
+
}
|
|
39
|
+
return valid;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
logger?.error?.(`Failed to parse package.json at ${packageJsonPath}:`, error);
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
exports.loadSdkPackagesFromPackageJson = loadSdkPackagesFromPackageJson;
|
|
48
|
+
/**
|
|
49
|
+
* Generates a safe URI from a package name
|
|
50
|
+
* @param packageName The npm package name
|
|
51
|
+
* @returns A URI-safe identifier
|
|
52
|
+
*/
|
|
53
|
+
const generateUri = (packageName) => `${RESOURCE_URI_PREFIX}://${packageName.replace(/[^a-z0-9.]/gi, '-')}`;
|
|
54
|
+
exports.generateUri = generateUri;
|
|
55
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/helpers/utils.ts"],"names":[],"mappings":";;;AAAA,qCAGiB;AACjB,yCAEmB;AAKnB,2CAA2C;AAC3C,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAE1C,iGAAiG;AACjG,MAAM,0BAA0B,GAAG,sCAAsC,CAAC;AAE1E;;;;;GAKG;AACI,MAAM,kBAAkB,GAAG,CAAC,WAAmB,EAAW,EAAE,CACjE,OAAO,CAAC,WAAW,CAAC;OACjB,OAAO,WAAW,KAAK,QAAQ;OAC/B,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAHrC,QAAA,kBAAkB,sBAGmB;AAElD;;;;;GAKG;AACI,MAAM,8BAA8B,GAAG,CAAC,WAAmB,EAAE,MAAe,EAAY,EAAE;IAC/F,MAAM,eAAe,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAA,oBAAU,EAAC,eAAe,CAAC,EAAE,CAAC;QACjC,MAAM,EAAE,KAAK,EAAE,CAAC,4BAA4B,eAAe,EAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,eAAe,EAAE,MAAM,CAAC,CAA6C,CAAC;QAClH,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YAC7D,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,EAAE,IAAI,EAAE,CAAC,iDAAiD,GAAG,aAAa,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,KAAK,EAAE,CAAC,mCAAmC,eAAe,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9E,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAnBW,QAAA,8BAA8B,kCAmBzC;AAEF;;;;GAIG;AACI,MAAM,WAAW,GAAG,CAAC,WAAmB,EAAU,EAAE,CACzD,GAAG,mBAAmB,MAAM,WAAW,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,CAAC;AAD5D,QAAA,WAAW,eACiD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AmaMcpServer, type ResourceToolOptions, type ToolDefinition } from '@ama-mcp/core';
|
|
2
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for SDK context registration
|
|
5
|
+
*/
|
|
6
|
+
export interface SdkContextOptions extends Partial<ResourceToolOptions>, ToolDefinition {
|
|
7
|
+
/**
|
|
8
|
+
* Path to project root where package.json is located
|
|
9
|
+
* @default '.'
|
|
10
|
+
*/
|
|
11
|
+
projectPath?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Explicit list of SDK packages (overrides package.json sdkContext.packages)
|
|
14
|
+
*/
|
|
15
|
+
sdkPackages?: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Type of the response from the SDK context retriever tool
|
|
19
|
+
*/
|
|
20
|
+
export type SdkContextResponse = {
|
|
21
|
+
content: ({
|
|
22
|
+
type: 'text';
|
|
23
|
+
text: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'resource_link';
|
|
26
|
+
name: string;
|
|
27
|
+
uri: string;
|
|
28
|
+
})[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Register both SDK context resources and tool
|
|
32
|
+
* @param server MCP server instance
|
|
33
|
+
* @param options Configuration options
|
|
34
|
+
*/
|
|
35
|
+
export declare const registerSdkContextToolAndResources: (server: McpServer, options?: SdkContextOptions) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Create and configure an SDK Context MCP server
|
|
38
|
+
* @param options Configuration options for the server
|
|
39
|
+
* @returns Configured AmaMcpServer instance with SDK context tools and resources registered
|
|
40
|
+
*/
|
|
41
|
+
export declare const createSdkContextServer: (options?: SdkContextOptions) => AmaMcpServer;
|
|
42
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../../src/server/mcp-server.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,YAAY,EAIZ,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,SAAS,EACV,MAAM,yCAAyC,CAAC;AAyBjD;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,mBAAmB,CAAC,EAAE,cAAc;IACrF;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GACpC;QAAE,IAAI,EAAE,eAAe,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;CAC7D,CAAC;AAuGF;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,SAAS,EACjB,UAAS,iBAAsB,KAC9B,IAeF,CAAC;AAwDF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,UAAS,iBAAsB,KAAG,YAkBxE,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSdkContextServer = exports.registerSdkContextToolAndResources = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const core_1 = require("@ama-mcp/core");
|
|
7
|
+
const telemetry_1 = require("@o3r/telemetry");
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const context_1 = require("../helpers/context");
|
|
10
|
+
const utils_1 = require("../helpers/utils");
|
|
11
|
+
/** Filename for SDK context documentation */
|
|
12
|
+
const SDK_CONTEXT_FILENAME = 'SDK_CONTEXT.md';
|
|
13
|
+
/** Filename for SDK usage instructions */
|
|
14
|
+
const INSTRUCTIONS_FILENAME = 'INSTRUCTIONS.md';
|
|
15
|
+
/** URI for the instructions resource */
|
|
16
|
+
const INSTRUCTIONS_URI = 'sdk-context://instructions';
|
|
17
|
+
/**
|
|
18
|
+
* Register a single SDK context as a resource
|
|
19
|
+
* @param server MCP server instance
|
|
20
|
+
* @param ctx SDK context info
|
|
21
|
+
*/
|
|
22
|
+
const registerSingleResource = (server, ctx) => {
|
|
23
|
+
core_1.resourceRegistry.set(ctx.uri, ctx.content);
|
|
24
|
+
server.registerResource(`SDK Context: ${ctx.packageName}`, ctx.uri, {
|
|
25
|
+
title: `SDK Context for ${ctx.packageName}`,
|
|
26
|
+
description: `API structure and domain information for ${ctx.packageName}.
|
|
27
|
+
Use this to avoid hallucinations when implementing features with this SDK.`,
|
|
28
|
+
mimeType: 'text/markdown'
|
|
29
|
+
}, () => ({ contents: [{ uri: ctx.uri, text: ctx.content }] }));
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Factory that creates a retriever for SDK context information
|
|
33
|
+
* @param contexts Loaded SDK contexts
|
|
34
|
+
* @param logger Logger instance
|
|
35
|
+
* @returns Retriever that fetches SDK context by package name
|
|
36
|
+
*/
|
|
37
|
+
const sdkContextRetriever = (contexts, logger) => ({ packageName }) => {
|
|
38
|
+
if (!(0, utils_1.isValidPackageName)(packageName)) {
|
|
39
|
+
logger.warn?.(`Invalid package name requested: "${packageName}"`);
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{ type: 'text', text: `Invalid package name: "${packageName}". Package names must follow npm naming conventions.` }
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const ctx = contexts.find((c) => c.packageName === packageName);
|
|
47
|
+
if (ctx) {
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{ type: 'text', text: ctx.content },
|
|
51
|
+
{ type: 'resource_link', name: `SDK Context: ${ctx.packageName}`, uri: ctx.uri }
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: `No SDK_CONTEXT.md found for package "${packageName}". Check that:\n
|
|
60
|
+
1. The package is listed in package.json sdkContext.packages or provided via CLI args\n
|
|
61
|
+
2. The package has SDK_CONTEXT.md generated`
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Register the SDK context tool on the server
|
|
68
|
+
* @param server MCP server instance
|
|
69
|
+
* @param contexts Loaded SDK contexts
|
|
70
|
+
* @param logger Logger instance
|
|
71
|
+
* @param toolOptions Tool definition options
|
|
72
|
+
*/
|
|
73
|
+
const registerTool = (server, contexts, logger, toolOptions) => {
|
|
74
|
+
const { toolName = 'get_sdk_context', toolTitle = 'Get SDK Context', toolDescription = `Retrieve SDK context information for configured SDK packages to understand their
|
|
75
|
+
API structure, available operations, and models. Use this before implementing features that rely on
|
|
76
|
+
an SDK to avoid hallucinations.` } = toolOptions;
|
|
77
|
+
logger.info?.(`Registering SDK context tool with ${contexts.length} contexts`);
|
|
78
|
+
server.registerTool(toolName, {
|
|
79
|
+
title: toolTitle,
|
|
80
|
+
description: toolDescription,
|
|
81
|
+
annotations: {
|
|
82
|
+
readOnlyHint: true,
|
|
83
|
+
openWorldHint: false
|
|
84
|
+
},
|
|
85
|
+
inputSchema: {
|
|
86
|
+
packageName: zod_1.z.string()
|
|
87
|
+
.describe('The npm package name of the SDK (e.g., "@my-scope/my-sdk-package")')
|
|
88
|
+
}
|
|
89
|
+
}, sdkContextRetriever(contexts, logger));
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Register both SDK context resources and tool
|
|
93
|
+
* @param server MCP server instance
|
|
94
|
+
* @param options Configuration options
|
|
95
|
+
*/
|
|
96
|
+
const registerSdkContextToolAndResources = (server, options = {}) => {
|
|
97
|
+
const projectPath = options.projectPath ?? '.';
|
|
98
|
+
const logger = options.logger || new core_1.MCPLogger('@ama-mcp/sdk');
|
|
99
|
+
const sdkPackages = options.sdkPackages ?? (0, utils_1.loadSdkPackagesFromPackageJson)(projectPath, logger);
|
|
100
|
+
const contexts = (0, context_1.loadSdkContexts)(sdkPackages, SDK_CONTEXT_FILENAME, logger);
|
|
101
|
+
// Register resources
|
|
102
|
+
logger.info?.(`Registering ${contexts.length} SDK context resources`);
|
|
103
|
+
contexts.forEach((ctx) => registerSingleResource(server, ctx));
|
|
104
|
+
// Register tool
|
|
105
|
+
registerTool(server, contexts, logger, options);
|
|
106
|
+
// Register instructions
|
|
107
|
+
registerInstructionsResource(server, logger);
|
|
108
|
+
};
|
|
109
|
+
exports.registerSdkContextToolAndResources = registerSdkContextToolAndResources;
|
|
110
|
+
/**
|
|
111
|
+
* Load the instructions content from the bundled INSTRUCTIONS.md file
|
|
112
|
+
* @param logger Optional logger for debug output
|
|
113
|
+
* @returns The instructions content or null if not found
|
|
114
|
+
*/
|
|
115
|
+
const loadInstructionsContent = (logger) => {
|
|
116
|
+
try {
|
|
117
|
+
// Resolve the path relative to this module's location (dist/src/index.js -> dist/resources/INSTRUCTIONS.md)
|
|
118
|
+
const instructionsPath = (0, node_path_1.resolve)(__dirname, '..', '..', 'resources', INSTRUCTIONS_FILENAME);
|
|
119
|
+
if (!(0, node_fs_1.existsSync)(instructionsPath)) {
|
|
120
|
+
logger?.debug?.(`Instructions file not found at ${instructionsPath}`);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return (0, node_fs_1.readFileSync)(instructionsPath, 'utf8');
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
logger?.error?.('Failed to load instructions:', error);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Register the SDK context usage instructions as an MCP resource
|
|
132
|
+
* @param server MCP server instance
|
|
133
|
+
* @param logger Optional logger for debug output
|
|
134
|
+
*/
|
|
135
|
+
const registerInstructionsResource = (server, logger) => {
|
|
136
|
+
const content = loadInstructionsContent(logger);
|
|
137
|
+
if (!content) {
|
|
138
|
+
logger?.warn?.('Could not load SDK context instructions');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
core_1.resourceRegistry.set(INSTRUCTIONS_URI, content);
|
|
142
|
+
server.registerResource('SDK Context Instructions', INSTRUCTIONS_URI, {
|
|
143
|
+
title: 'SDK Context Usage Instructions',
|
|
144
|
+
description: `Guidelines for using SDK context to avoid hallucinations when implementing features with installed SDKs.
|
|
145
|
+
Read this before using the get_sdk_context tool.`,
|
|
146
|
+
mimeType: 'text/markdown'
|
|
147
|
+
}, () => ({ contents: [{ uri: INSTRUCTIONS_URI, text: content }] }));
|
|
148
|
+
logger?.info?.('Registered SDK context instructions resource');
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Create and configure an SDK Context MCP server
|
|
152
|
+
* @param options Configuration options for the server
|
|
153
|
+
* @returns Configured AmaMcpServer instance with SDK context tools and resources registered
|
|
154
|
+
*/
|
|
155
|
+
const createSdkContextServer = (options = {}) => {
|
|
156
|
+
const name = '@ama-mcp/sdk';
|
|
157
|
+
const logger = options.logger ?? new core_1.MCPLogger(name, options.logLevel);
|
|
158
|
+
const server = new core_1.AmaMcpServer(logger, {
|
|
159
|
+
name,
|
|
160
|
+
version: '0.0.0'
|
|
161
|
+
});
|
|
162
|
+
void (0, telemetry_1.sendGenAIEventMetricsIfAuthorized)(name, 'registrationStart', { logger });
|
|
163
|
+
(0, exports.registerSdkContextToolAndResources)(server, { ...options, logger });
|
|
164
|
+
void (0, telemetry_1.sendGenAIEventMetricsIfAuthorized)(name, 'registrationEnd', { logger });
|
|
165
|
+
return server;
|
|
166
|
+
};
|
|
167
|
+
exports.createSdkContextServer = createSdkContextServer;
|
|
168
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../../src/server/mcp-server.ts"],"names":[],"mappings":"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"}
|