Skip to content

Commit 559e903

Browse files
committed
feat: add a mcp server to load the different SDK context
1 parent ef2751e commit 559e903

File tree

20 files changed

+1426
-1
lines changed

20 files changed

+1426
-1
lines changed

nx.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,22 @@
367367
],
368368
"cache": true
369369
},
370+
"expose-resources": {
371+
"executor": "nx:run-script",
372+
"options": {
373+
"script": "copy:resources"
374+
},
375+
"dependsOn": [
376+
"compile"
377+
],
378+
"inputs": [
379+
"{projectRoot}/resources/**"
380+
],
381+
"outputs": [
382+
"{projectRoot}/dist/resources/**"
383+
],
384+
"cache": true
385+
},
370386
"expose-schemas": {
371387
"executor": "nx:run-script",
372388
"options": {

packages/@ama-mcp/sdk/README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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`, 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+
### Option 1: VS Code `mcp.json` (Recommended)
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+
### Option 2: Project `package.json`
32+
33+
Add to your project's `package.json` (used as fallback if no args provided):
34+
35+
```json
36+
{
37+
"sdkContext": {
38+
"packages": [
39+
"@my-scope/my-sdk-package",
40+
"@other-scope/other-sdk"
41+
]
42+
}
43+
}
44+
```
45+
46+
## Usage
47+
48+
### CLI (for mcp.json)
49+
50+
```bash
51+
# Specify packages with --packages flag
52+
ama-mcp-sdk --packages @my-scope/my-sdk @other-scope/other-sdk
53+
54+
# Show help
55+
ama-mcp-sdk --help
56+
```
57+
58+
### Programmatic (in custom MCP server)
59+
60+
```typescript
61+
import { registerSdkContextToolAndResources } from '@ama-mcp/sdk';
62+
63+
// With explicit packages
64+
await registerSdkContextToolAndResources(server, {
65+
sdkPackages: ['@my-scope/my-sdk']
66+
});
67+
68+
// Or reads from package.json sdkContext.packages automatically
69+
await registerSdkContextToolAndResources(server);
70+
```
71+
72+
### Available Tool
73+
74+
**`get_sdk_context`** - Retrieve SDK context for configured packages
75+
76+
```
77+
// List all configured SDKs with context
78+
get_sdk_context()
79+
80+
// Get context for specific package
81+
get_sdk_context({ packageName: "@my-scope/my-sdk-package" })
82+
```
83+
84+
### Available Resources
85+
86+
**`sdk-context://instructions`** - Usage guidelines for AI assistants
87+
88+
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.
89+
90+
**`sdk-context://<package-name>`** - SDK context for each configured package
91+
92+
Each configured SDK package that has an `SDK_CONTEXT.md` file is exposed as a resource.
93+
94+
## How It Works
95+
96+
1. Reads `sdkContext.packages` from project's `package.json` or uses CLI arguments
97+
2. Uses Node.js `require.resolve()` to automatically locate packages
98+
3. Loads `SDK_CONTEXT.md` from each resolved package
99+
4. Registers each as an MCP resource
100+
5. Provides a tool for AI assistants to query SDK information
101+
102+
## Package Resolution
103+
104+
The SDK automatically discovers packages using Node.js's `require.resolve()`. This means:
105+
106+
- **No manual path configuration needed** - packages are found automatically
107+
- **Works with workspaces** - supports npm/yarn/pnpm workspace configurations
108+
- **Flexible installation** - works with local, global, or custom module paths
109+
- **Error handling** - clear error messages when packages aren't found
110+
111+
If a package isn't found, ensure:
112+
1. The package is installed (`npm install <package-name>`)
113+
2. The package name is spelled correctly
114+
3. The package has an `SDK_CONTEXT.md` file in its root
115+
116+
**Security**: The system validates package names to prevent path traversal attacks and only accepts valid npm package name patterns.
117+
118+
## Troubleshooting
119+
120+
### Package Not Found
121+
```
122+
Package "@my-scope/my-sdk" not found. Is it installed?
123+
```
124+
**Solution**: Install the package or verify the name in your configuration.
125+
126+
### No SDK_CONTEXT.md Found
127+
```
128+
No SDK_CONTEXT.md found for @my-scope/my-sdk
129+
```
130+
**Solution**: Generate the context file using the command below.
131+
132+
## Generating SDK Context
133+
134+
SDK maintainers can generate `SDK_CONTEXT.md` using:
135+
136+
```bash
137+
cd /path/to/sdk-project
138+
npx amasdk-update-sdk-context --interactive
139+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import shared from '../../../eslint.shared.config.mjs';
2+
import local from './eslint.local.config.mjs';
3+
4+
export default [
5+
...shared,
6+
...local
7+
];
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
dirname,
3+
} from 'node:path';
4+
import {
5+
fileURLToPath,
6+
} from 'node:url';
7+
import globals from 'globals';
8+
9+
const __filename = fileURLToPath(import.meta.url);
10+
// __dirname is not defined in ES module scope
11+
const __dirname = dirname(__filename);
12+
13+
export default [
14+
{
15+
name: '@ama-mcp/sdk/projects',
16+
languageOptions: {
17+
sourceType: 'module',
18+
parserOptions: {
19+
tsconfigRootDir: __dirname,
20+
projectService: true
21+
},
22+
globals: {
23+
...globals.node,
24+
NodeJS: true
25+
}
26+
}
27+
}
28+
];
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const { getJestProjectConfig } = require('@o3r/test-helpers');
2+
3+
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
4+
module.exports = {
5+
...getJestProjectConfig(),
6+
projects: [
7+
'<rootDir>/testing/jest.config.ut.js'
8+
]
9+
};

packages/@ama-mcp/sdk/package.json

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"name": "@ama-mcp/sdk",
3+
"version": "0.0.0-placeholder",
4+
"publishConfig": {
5+
"access": "public"
6+
},
7+
"description": "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+
"module": "dist/src/public_api.js",
15+
"typings": "dist/src/public_api.d.ts",
16+
"sideEffects": false,
17+
"bin": {
18+
"ama-mcp-sdk": "./dist/src/cli.js"
19+
},
20+
"exports": {
21+
"./package.json": {
22+
"default": "./package.json"
23+
},
24+
".": {
25+
"typings": "./dist/src/public_api.d.ts",
26+
"default": "./dist/src/public_api.js"
27+
}
28+
},
29+
"scripts": {
30+
"nx": "nx",
31+
"ng": "yarn nx",
32+
"build": "yarn nx build ama-mcp-sdk",
33+
"compile": "tsc -b ./tsconfig.build.json && yarn cpy package.json dist && patch-package-json-main",
34+
"copy:resources": "yarn cpy resources dist"
35+
},
36+
"peerDependencies": {
37+
"@ama-mcp/core": "workspace:~",
38+
"@modelcontextprotocol/sdk": "^1.19.0",
39+
"zod": "^3.0.0 || ^4.0.0"
40+
},
41+
"dependencies": {
42+
"@o3r/telemetry": "workspace:~",
43+
"commander": "^14.0.0",
44+
"tslib": "^2.6.2"
45+
},
46+
"devDependencies": {
47+
"@ama-mcp/core": "workspace:~",
48+
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
49+
"@modelcontextprotocol/sdk": "~1.27.0",
50+
"@nx/eslint": "~22.5.3",
51+
"@nx/eslint-plugin": "~22.5.3",
52+
"@nx/jest": "~22.5.3",
53+
"@nx/js": "~22.5.3",
54+
"@o3r/build-helpers": "workspace:^",
55+
"@o3r/eslint-config": "workspace:^",
56+
"@o3r/eslint-plugin": "workspace:^",
57+
"@o3r/test-helpers": "workspace:^",
58+
"@stylistic/eslint-plugin": "~5.7.0",
59+
"@types/jest": "~30.0.0",
60+
"@types/node": "~24.10.0",
61+
"@typescript-eslint/parser": "~8.54.0",
62+
"cpy-cli": "^6.0.0",
63+
"eslint": "~9.39.0",
64+
"eslint-import-resolver-node": "~0.3.9",
65+
"eslint-import-resolver-typescript": "~4.4.0",
66+
"eslint-plugin-import": "~2.32.0",
67+
"eslint-plugin-import-newlines": "~1.4.0",
68+
"eslint-plugin-jest": "~29.12.0",
69+
"eslint-plugin-jsdoc": "~61.7.0",
70+
"eslint-plugin-prefer-arrow": "~1.2.3",
71+
"eslint-plugin-unicorn": "~62.0.0",
72+
"eslint-plugin-unused-imports": "~4.3.0",
73+
"globals": "^16.0.0",
74+
"jest": "~30.2.0",
75+
"jest-junit": "~16.0.0",
76+
"jsonc-eslint-parser": "~2.4.0",
77+
"ts-jest": "~29.4.0",
78+
"typescript": "~5.9.2",
79+
"typescript-eslint": "~8.54.0",
80+
"zod": "~4.3.0"
81+
},
82+
"engines": {
83+
"node": "^22.17.0 || ^24.0.0"
84+
}
85+
}

packages/@ama-mcp/sdk/project.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "ama-mcp-sdk",
3+
"$schema": "https://raw.githubusercontent.com/nrwl/nx/master/packages/nx/schemas/project-schema.json",
4+
"projectType": "library",
5+
"sourceRoot": "packages/@ama-mcp/sdk/src",
6+
"prefix": "o3r",
7+
"targets": {
8+
"build": {
9+
"executor": "nx:noop",
10+
"dependsOn": ["compile", "expose-templates", "expose-resources"]
11+
},
12+
"compile": {
13+
"executor": "nx:run-script",
14+
"options": {
15+
"script": "compile"
16+
},
17+
"dependsOn": ["prepare", "^build"]
18+
},
19+
"expose-resources": {},
20+
"test": {},
21+
"lint": {},
22+
"prepare-publish": {},
23+
"publish": {}
24+
},
25+
"tags": []
26+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

0 commit comments

Comments
 (0)