@stacksfinder/mcp-server 1.3.4 → 1.3.6
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/CHANGELOG.md +100 -0
- package/CONTRIBUTING.md +164 -0
- package/README.md +13 -0
- package/SECURITY.md +124 -0
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +14 -13
- package/dist/data/index.js.map +1 -1
- package/dist/http.d.ts +11 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +80 -0
- package/dist/http.js.map +1 -0
- package/dist/tools/list-techs.d.ts +2 -2
- package/package.json +17 -3
- package/dist/__tests__/mcp-tools.test.d.ts +0 -8
- package/dist/__tests__/mcp-tools.test.d.ts.map +0 -1
- package/dist/__tests__/mcp-tools.test.js +0 -345
- package/dist/__tests__/mcp-tools.test.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@stacksfinder/mcp-server` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.3.5] - 2025-01-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Smithery deployment requirements guide
|
|
12
|
+
- HTTP entry point for cloud deployment
|
|
13
|
+
- Chaos tests for MCP suggestions algorithm
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Default export for Cloudflare Workers compatibility
|
|
17
|
+
- Prevent server auto-start during Smithery scan
|
|
18
|
+
- Static JSON imports for Smithery bundling
|
|
19
|
+
- CJS compatibility + sandbox server mode
|
|
20
|
+
|
|
21
|
+
## [1.3.0] - 2025-01-10
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- `estimate_project` tool - Scope, pricing, and market analysis
|
|
25
|
+
- `get_estimate_quota` tool - Check remaining estimate quota
|
|
26
|
+
- Deterministic pricing algorithm by region and seniority
|
|
27
|
+
|
|
28
|
+
## [1.2.2] - 2025-01-08
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Tool annotations for VS Code Copilot integration
|
|
32
|
+
- Integration tests for all tools
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- Correct `recommend_stack` API request format
|
|
36
|
+
|
|
37
|
+
## [1.2.0] - 2025-01-06
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
- `check_mcp_compatibility` tool - Detect conflicts and synergies between MCPs
|
|
41
|
+
- Enhanced project-kit tools with smarter detection
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- Total tools increased to 21
|
|
45
|
+
|
|
46
|
+
## [1.1.0] - 2025-01-04
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
- Project Kit Phase 2 tools:
|
|
50
|
+
- `generate_mcp_kit` - Generate tech stack + MCP recommendations
|
|
51
|
+
- `analyze_repo_mcps` - Analyze repository and recommend MCPs
|
|
52
|
+
- `prepare_mcp_installation` - Generate .env-mcp configuration
|
|
53
|
+
- `execute_mcp_installation` - Generate IDE-specific install commands
|
|
54
|
+
- Interactive installation workflow
|
|
55
|
+
- Enhanced MCP suggestions algorithm
|
|
56
|
+
|
|
57
|
+
## [1.0.5] - 2025-01-02
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- `get_migration_recommendation` tool - Analyze audits for migration opportunities
|
|
61
|
+
- Docker support for Glama.ai hosting
|
|
62
|
+
- Smithery deployment configuration
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
- Use npm install instead of npm ci in Dockerfile
|
|
66
|
+
|
|
67
|
+
## [1.0.0] - 2024-12-28
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
- Initial release with 16 core tools
|
|
71
|
+
- **Free Tier Tools:**
|
|
72
|
+
- `list_technologies` - Browse technology catalog
|
|
73
|
+
- `analyze_tech` - 6-dimension technology analysis
|
|
74
|
+
- `compare_techs` - Side-by-side comparison
|
|
75
|
+
- `recommend_stack_demo` - 1x/day free recommendation
|
|
76
|
+
- **Pro Tier Tools:**
|
|
77
|
+
- `recommend_stack` - Unlimited recommendations
|
|
78
|
+
- `create_blueprint` - Generate AI-powered blueprints
|
|
79
|
+
- `get_blueprint` - Fetch existing blueprints
|
|
80
|
+
- `setup_api_key` - API key management
|
|
81
|
+
- `list_api_keys` / `revoke_api_key` - Key lifecycle
|
|
82
|
+
- **Audit Tools:**
|
|
83
|
+
- `create_audit` - Technical debt analysis
|
|
84
|
+
- `get_audit` / `list_audits` - Audit retrieval
|
|
85
|
+
- `compare_audits` - Progress tracking
|
|
86
|
+
- `get_audit_quota` - Quota management
|
|
87
|
+
- Multi-platform installation (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code)
|
|
88
|
+
- MIT License
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Tool Categories (v1.3.5)
|
|
93
|
+
|
|
94
|
+
| Category | Tools | Auth Required |
|
|
95
|
+
|----------|-------|---------------|
|
|
96
|
+
| Free | 9 | No |
|
|
97
|
+
| Pro | 6 | API Key |
|
|
98
|
+
| Audit | 6 | API Key |
|
|
99
|
+
| Estimator | 2 | API Key |
|
|
100
|
+
| **Total** | **23** | - |
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Contributing to StacksFinder MCP Server
|
|
2
|
+
|
|
3
|
+
First off, thank you for considering contributing to StacksFinder MCP Server! This document provides guidelines and information about contributing.
|
|
4
|
+
|
|
5
|
+
## Code of Conduct
|
|
6
|
+
|
|
7
|
+
By participating in this project, you agree to maintain a respectful and inclusive environment for everyone.
|
|
8
|
+
|
|
9
|
+
## How Can I Contribute?
|
|
10
|
+
|
|
11
|
+
### Reporting Bugs
|
|
12
|
+
|
|
13
|
+
Before creating bug reports, please check the [existing issues](https://github.com/hoklims/stacksfinder-mcp/issues) to avoid duplicates.
|
|
14
|
+
|
|
15
|
+
When creating a bug report, include:
|
|
16
|
+
|
|
17
|
+
- **Clear title** describing the issue
|
|
18
|
+
- **Steps to reproduce** the behavior
|
|
19
|
+
- **Expected behavior** vs. actual behavior
|
|
20
|
+
- **Environment details:**
|
|
21
|
+
- Node.js version (`node --version`)
|
|
22
|
+
- MCP client (Claude Code, Cursor, etc.)
|
|
23
|
+
- Operating system
|
|
24
|
+
- **Error messages** and logs if applicable
|
|
25
|
+
|
|
26
|
+
### Suggesting Features
|
|
27
|
+
|
|
28
|
+
Feature requests are welcome! Please:
|
|
29
|
+
|
|
30
|
+
1. Check if the feature has already been requested
|
|
31
|
+
2. Provide a clear use case
|
|
32
|
+
3. Explain how it benefits the broader community
|
|
33
|
+
|
|
34
|
+
### Pull Requests
|
|
35
|
+
|
|
36
|
+
1. **Fork the repository**
|
|
37
|
+
2. **Create a feature branch:**
|
|
38
|
+
```bash
|
|
39
|
+
git checkout -b feature/your-feature-name
|
|
40
|
+
```
|
|
41
|
+
3. **Make your changes**
|
|
42
|
+
4. **Run tests:**
|
|
43
|
+
```bash
|
|
44
|
+
bun test --run
|
|
45
|
+
```
|
|
46
|
+
5. **Ensure TypeScript compiles:**
|
|
47
|
+
```bash
|
|
48
|
+
bun run build
|
|
49
|
+
```
|
|
50
|
+
6. **Commit with a clear message:**
|
|
51
|
+
```bash
|
|
52
|
+
git commit -m "feat: add new capability to analyze_tech"
|
|
53
|
+
```
|
|
54
|
+
7. **Push and create a PR**
|
|
55
|
+
|
|
56
|
+
## Development Setup
|
|
57
|
+
|
|
58
|
+
### Prerequisites
|
|
59
|
+
|
|
60
|
+
- Node.js >= 18.0.0
|
|
61
|
+
- Bun (recommended) or npm
|
|
62
|
+
|
|
63
|
+
### Installation
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Clone the repository
|
|
67
|
+
git clone https://github.com/hoklims/stacksfinder-mcp.git
|
|
68
|
+
cd stacksfinder-mcp/packages/mcp-server
|
|
69
|
+
|
|
70
|
+
# Install dependencies
|
|
71
|
+
bun install
|
|
72
|
+
|
|
73
|
+
# Build
|
|
74
|
+
bun run build
|
|
75
|
+
|
|
76
|
+
# Run tests
|
|
77
|
+
bun test
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Project Structure
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
packages/mcp-server/
|
|
84
|
+
├── src/
|
|
85
|
+
│ ├── index.ts # Entry point (stdio transport)
|
|
86
|
+
│ ├── server.ts # MCP server factory
|
|
87
|
+
│ ├── tools/ # Tool implementations
|
|
88
|
+
│ │ ├── analyze.ts
|
|
89
|
+
│ │ ├── compare.ts
|
|
90
|
+
│ │ └── ...
|
|
91
|
+
│ ├── utils/ # Shared utilities
|
|
92
|
+
│ │ ├── api-client.ts
|
|
93
|
+
│ │ ├── config.ts
|
|
94
|
+
│ │ └── logger.ts
|
|
95
|
+
│ └── data/ # Scoring data (copied from main app)
|
|
96
|
+
├── tests/ # Test suites
|
|
97
|
+
├── dist/ # Build output
|
|
98
|
+
└── package.json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Adding a New Tool
|
|
102
|
+
|
|
103
|
+
1. Create a new file in `src/tools/your-tool.ts`:
|
|
104
|
+
```typescript
|
|
105
|
+
import { z } from 'zod';
|
|
106
|
+
import type { ToolHandler } from '../types';
|
|
107
|
+
|
|
108
|
+
const InputSchema = z.object({
|
|
109
|
+
param: z.string().describe('Parameter description')
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export const yourTool: ToolHandler = {
|
|
113
|
+
name: 'your_tool',
|
|
114
|
+
description: 'What this tool does',
|
|
115
|
+
inputSchema: InputSchema,
|
|
116
|
+
handler: async (input, context) => {
|
|
117
|
+
// Implementation
|
|
118
|
+
return { content: [{ type: 'text', text: 'Result' }] };
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
2. Register in `src/server.ts`
|
|
124
|
+
3. Add tests in `tests/your-tool.test.ts`
|
|
125
|
+
4. Update README.md with the new tool
|
|
126
|
+
|
|
127
|
+
## Coding Guidelines
|
|
128
|
+
|
|
129
|
+
### TypeScript
|
|
130
|
+
|
|
131
|
+
- Use strict TypeScript (`strict: true`)
|
|
132
|
+
- No `any` types without justification
|
|
133
|
+
- Export types for public APIs
|
|
134
|
+
- Use Zod for input validation
|
|
135
|
+
|
|
136
|
+
### Testing
|
|
137
|
+
|
|
138
|
+
- Write tests for all new tools
|
|
139
|
+
- Maintain existing test coverage
|
|
140
|
+
- Use descriptive test names:
|
|
141
|
+
```typescript
|
|
142
|
+
it('should return error when technology ID is invalid', () => {});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Commit Messages
|
|
146
|
+
|
|
147
|
+
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
148
|
+
|
|
149
|
+
- `feat:` New feature
|
|
150
|
+
- `fix:` Bug fix
|
|
151
|
+
- `docs:` Documentation only
|
|
152
|
+
- `test:` Adding tests
|
|
153
|
+
- `refactor:` Code refactoring
|
|
154
|
+
- `chore:` Maintenance tasks
|
|
155
|
+
|
|
156
|
+
## Questions?
|
|
157
|
+
|
|
158
|
+
- Open a [GitHub Discussion](https://github.com/hoklims/stacksfinder-mcp/discussions)
|
|
159
|
+
- Join our [Discord](https://discord.gg/FqBqKe9N)
|
|
160
|
+
- Email: hello@stacksfinder.com
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@stacksfinder/mcp-server)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://modelcontextprotocol.io)
|
|
5
6
|
[](https://lobehub.com/fr/mcp/hoklims-stacksfinder-mcp)
|
|
6
7
|
|
|
7
8
|
MCP (Model Context Protocol) server that brings **deterministic tech stack recommendations** to LLM clients like Claude, Cursor, Windsurf, and other MCP-compatible tools.
|
|
@@ -460,6 +461,18 @@ bun run dev # Watch mode
|
|
|
460
461
|
bun test # Run tests
|
|
461
462
|
```
|
|
462
463
|
|
|
464
|
+
## Contributing
|
|
465
|
+
|
|
466
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) before submitting a Pull Request.
|
|
467
|
+
|
|
468
|
+
For security vulnerabilities, please see our [Security Policy](SECURITY.md).
|
|
469
|
+
|
|
470
|
+
## Documentation
|
|
471
|
+
|
|
472
|
+
- [CHANGELOG.md](CHANGELOG.md) - Version history and release notes
|
|
473
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) - How to contribute
|
|
474
|
+
- [SECURITY.md](SECURITY.md) - Security policy and vulnerability reporting
|
|
475
|
+
|
|
463
476
|
## Links
|
|
464
477
|
|
|
465
478
|
- **Website**: [stacksfinder.com](https://stacksfinder.com)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
| ------- | ------------------ |
|
|
7
|
+
| 1.3.x | :white_check_mark: |
|
|
8
|
+
| 1.2.x | :white_check_mark: |
|
|
9
|
+
| < 1.2 | :x: |
|
|
10
|
+
|
|
11
|
+
## Reporting a Vulnerability
|
|
12
|
+
|
|
13
|
+
We take security seriously. If you discover a security vulnerability, please report it responsibly.
|
|
14
|
+
|
|
15
|
+
### How to Report
|
|
16
|
+
|
|
17
|
+
**DO NOT** open a public GitHub issue for security vulnerabilities.
|
|
18
|
+
|
|
19
|
+
Instead, please email us at: **security@stacksfinder.com**
|
|
20
|
+
|
|
21
|
+
Include:
|
|
22
|
+
- Description of the vulnerability
|
|
23
|
+
- Steps to reproduce
|
|
24
|
+
- Potential impact
|
|
25
|
+
- Suggested fix (if any)
|
|
26
|
+
|
|
27
|
+
### What to Expect
|
|
28
|
+
|
|
29
|
+
1. **Acknowledgment:** We will acknowledge your report within 48 hours
|
|
30
|
+
2. **Assessment:** We will investigate and assess the severity within 7 days
|
|
31
|
+
3. **Resolution:** Critical issues will be patched within 14 days
|
|
32
|
+
4. **Disclosure:** We will coordinate responsible disclosure with you
|
|
33
|
+
|
|
34
|
+
### Scope
|
|
35
|
+
|
|
36
|
+
The following are in scope:
|
|
37
|
+
|
|
38
|
+
- `@stacksfinder/mcp-server` npm package
|
|
39
|
+
- StacksFinder API (api.stacksfinder.com)
|
|
40
|
+
- Authentication and API key handling
|
|
41
|
+
- Data validation and sanitization
|
|
42
|
+
|
|
43
|
+
### Out of Scope
|
|
44
|
+
|
|
45
|
+
- Third-party dependencies (report to their maintainers)
|
|
46
|
+
- Social engineering attacks
|
|
47
|
+
- Physical security
|
|
48
|
+
- Denial of service attacks
|
|
49
|
+
|
|
50
|
+
## Security Best Practices
|
|
51
|
+
|
|
52
|
+
### API Key Handling
|
|
53
|
+
|
|
54
|
+
- **Never commit API keys** to version control
|
|
55
|
+
- Store keys in environment variables or secure vaults
|
|
56
|
+
- Use `.env` files locally (add to `.gitignore`)
|
|
57
|
+
- Rotate keys if you suspect compromise
|
|
58
|
+
|
|
59
|
+
### Configuration
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Good: Environment variable
|
|
63
|
+
export STACKSFINDER_API_KEY="sk_..."
|
|
64
|
+
|
|
65
|
+
# Good: .env file (not committed)
|
|
66
|
+
echo "STACKSFINDER_API_KEY=sk_..." >> .env
|
|
67
|
+
echo ".env" >> .gitignore
|
|
68
|
+
|
|
69
|
+
# Bad: Hardcoded in code
|
|
70
|
+
const API_KEY = "sk_..." # NEVER DO THIS
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### MCP Configuration Security
|
|
74
|
+
|
|
75
|
+
When configuring the MCP server:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"mcpServers": {
|
|
80
|
+
"stacksfinder": {
|
|
81
|
+
"command": "npx",
|
|
82
|
+
"args": ["-y", "@stacksfinder/mcp-server"],
|
|
83
|
+
"env": {
|
|
84
|
+
"STACKSFINDER_API_KEY": "${STACKSFINDER_API_KEY}"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Use environment variable references (`${VAR}`) instead of hardcoding secrets.
|
|
92
|
+
|
|
93
|
+
## Security Features
|
|
94
|
+
|
|
95
|
+
### Input Validation
|
|
96
|
+
|
|
97
|
+
All tool inputs are validated using Zod schemas before processing:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const InputSchema = z.object({
|
|
101
|
+
technology: z.string().min(1).max(100),
|
|
102
|
+
context: z.enum(['default', 'mvp', 'enterprise'])
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Rate Limiting
|
|
107
|
+
|
|
108
|
+
- Free tier: 1 recommendation per day
|
|
109
|
+
- API requests are rate-limited per key
|
|
110
|
+
- Quota tracking prevents abuse
|
|
111
|
+
|
|
112
|
+
### Data Privacy
|
|
113
|
+
|
|
114
|
+
- No user data is stored locally
|
|
115
|
+
- API keys are transmitted over HTTPS only
|
|
116
|
+
- Logs do not contain sensitive information
|
|
117
|
+
|
|
118
|
+
## Acknowledgments
|
|
119
|
+
|
|
120
|
+
We appreciate the security research community. Reporters of valid vulnerabilities will be acknowledged (with permission) in our security hall of fame.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
**Contact:** security@stacksfinder.com
|
package/dist/data/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,gBAAgB,wEAAyE,CAAC;AACvG,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAO3D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,sGASb,CAAC;AACX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,QAAQ,2CAA4C,CAAC;AAClE,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,MAAM;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CAChC;AAwBD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAEzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,QAAQ,EAAE,CAE/C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAExE;AAED;;GAEG;AACH,wBAAgB,gCAAgC,IAAI,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAmB/E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,OAAmB,GAAG,MAAM,GAAG,IAAI,CAIrF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAclD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAcrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAWnG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAErE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAKhF"}
|
package/dist/data/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { createRequire } from 'module';
|
|
2
1
|
import { findSimilar } from '../utils/errors.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const compatibilityData = require('./compatibility_matrix.json');
|
|
2
|
+
// Import JSON directly - esbuild bundles these inline for Smithery
|
|
3
|
+
import techScoresData from './technology_scores.json' with { type: 'json' };
|
|
4
|
+
import compatibilityData from './compatibility_matrix.json' with { type: 'json' };
|
|
7
5
|
/**
|
|
8
6
|
* Data version - update when syncing from source.
|
|
9
7
|
*/
|
|
@@ -40,23 +38,26 @@ export const CATEGORIES = [
|
|
|
40
38
|
* Score contexts.
|
|
41
39
|
*/
|
|
42
40
|
export const CONTEXTS = ['default', 'mvp', 'enterprise'];
|
|
41
|
+
// Type assertions for imported JSON
|
|
42
|
+
const scores = techScoresData;
|
|
43
|
+
const compat = compatibilityData;
|
|
43
44
|
/**
|
|
44
45
|
* Get all technology IDs.
|
|
45
46
|
*/
|
|
46
47
|
export function getAllTechIds() {
|
|
47
|
-
return Object.keys(
|
|
48
|
+
return Object.keys(scores.technologies);
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
51
|
* Get a technology by ID.
|
|
51
52
|
*/
|
|
52
53
|
export function getTechnology(id) {
|
|
53
|
-
return
|
|
54
|
+
return scores.technologies[id] || null;
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* Get all technologies.
|
|
57
58
|
*/
|
|
58
59
|
export function getAllTechnologies() {
|
|
59
|
-
return Object.values(
|
|
60
|
+
return Object.values(scores.technologies);
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
63
|
* Get technologies by category.
|
|
@@ -140,8 +141,8 @@ export function getCompatibility(techA, techB) {
|
|
|
140
141
|
if (techA === techB)
|
|
141
142
|
return 100;
|
|
142
143
|
// Check both directions
|
|
143
|
-
const scoreAB =
|
|
144
|
-
const scoreBA =
|
|
144
|
+
const scoreAB = compat.matrix[techA]?.[techB];
|
|
145
|
+
const scoreBA = compat.matrix[techB]?.[techA];
|
|
145
146
|
// Return defined score, preferring A→B
|
|
146
147
|
if (scoreAB !== undefined)
|
|
147
148
|
return scoreAB;
|
|
@@ -189,15 +190,15 @@ export function findSimilarTechIds(input, limit = 3) {
|
|
|
189
190
|
* Check if a technology ID exists.
|
|
190
191
|
*/
|
|
191
192
|
export function techExists(id) {
|
|
192
|
-
return id in
|
|
193
|
+
return id in scores.technologies;
|
|
193
194
|
}
|
|
194
195
|
/**
|
|
195
196
|
* Get source data version from JSON files.
|
|
196
197
|
*/
|
|
197
198
|
export function getSourceDataVersion() {
|
|
198
199
|
return {
|
|
199
|
-
scores:
|
|
200
|
-
compatibility:
|
|
200
|
+
scores: scores.$version,
|
|
201
|
+
compatibility: compat.$version
|
|
201
202
|
};
|
|
202
203
|
}
|
|
203
204
|
//# sourceMappingURL=index.js.map
|
package/dist/data/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* HTTP entry point for Smithery hosted deployments.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates a sandbox server for Smithery capability scanning.
|
|
7
|
+
* Default export as required by Smithery.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createSandboxServer(): import("@modelcontextprotocol/sdk/server/mcp.js").McpServer;
|
|
10
|
+
export default createSandboxServer;
|
|
11
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AAEA;;GAEG;AAUH;;;GAGG;AACH,wBAAgB,mBAAmB,gEAElC;AAGD,eAAe,mBAAmB,CAAC"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* HTTP entry point for Smithery hosted deployments.
|
|
4
|
+
*/
|
|
5
|
+
import { createServer as createHttpServer } from 'node:http';
|
|
6
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
7
|
+
import { createServer } from './server.js';
|
|
8
|
+
import { loadConfig } from './utils/config.js';
|
|
9
|
+
import { setDebug, info, error } from './utils/logger.js';
|
|
10
|
+
const PORT = parseInt(process.env.PORT || '3000', 10);
|
|
11
|
+
/**
|
|
12
|
+
* Creates a sandbox server for Smithery capability scanning.
|
|
13
|
+
* Default export as required by Smithery.
|
|
14
|
+
*/
|
|
15
|
+
export function createSandboxServer() {
|
|
16
|
+
return createServer();
|
|
17
|
+
}
|
|
18
|
+
// Default export must be the createServer function for Smithery
|
|
19
|
+
export default createSandboxServer;
|
|
20
|
+
async function main() {
|
|
21
|
+
const config = loadConfig();
|
|
22
|
+
if (config.debug) {
|
|
23
|
+
setDebug(true);
|
|
24
|
+
info('Debug logging enabled');
|
|
25
|
+
}
|
|
26
|
+
const httpServer = createHttpServer(async (req, res) => {
|
|
27
|
+
if (req.method === 'GET' && req.url === '/health') {
|
|
28
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
29
|
+
res.end(JSON.stringify({ status: 'ok', version: '1.3.5' }));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (req.method === 'POST' && req.url === '/mcp') {
|
|
33
|
+
try {
|
|
34
|
+
let body = '';
|
|
35
|
+
for await (const chunk of req) {
|
|
36
|
+
body += chunk;
|
|
37
|
+
}
|
|
38
|
+
const jsonBody = JSON.parse(body);
|
|
39
|
+
const server = createServer();
|
|
40
|
+
const transport = new StreamableHTTPServerTransport({
|
|
41
|
+
sessionIdGenerator: undefined,
|
|
42
|
+
enableJsonResponse: true
|
|
43
|
+
});
|
|
44
|
+
res.on('finish', () => {
|
|
45
|
+
transport.close();
|
|
46
|
+
server.close();
|
|
47
|
+
});
|
|
48
|
+
await server.connect(transport);
|
|
49
|
+
await transport.handleRequest(req, res, jsonBody);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
error('Error handling MCP request', err);
|
|
53
|
+
if (!res.headersSent) {
|
|
54
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
55
|
+
res.end(JSON.stringify({
|
|
56
|
+
jsonrpc: '2.0',
|
|
57
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
58
|
+
id: null
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
65
|
+
res.end(JSON.stringify({ error: 'Not found' }));
|
|
66
|
+
});
|
|
67
|
+
httpServer.listen(PORT, '0.0.0.0', () => {
|
|
68
|
+
info(`StacksFinder MCP HTTP Server running on port ${PORT}`);
|
|
69
|
+
info('POST /mcp for MCP requests, GET /health for health checks');
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Only start server when run directly
|
|
73
|
+
const isDirectRun = process.argv[1]?.includes('http') || process.env.SMITHERY_RUN === 'true';
|
|
74
|
+
if (isDirectRun && !process.env.SMITHERY_SCAN) {
|
|
75
|
+
main().catch((err) => {
|
|
76
|
+
console.error('Fatal error:', err);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,9 +5,9 @@ import { z } from 'zod';
|
|
|
5
5
|
export declare const ListTechsInputSchema: z.ZodObject<{
|
|
6
6
|
category: z.ZodOptional<z.ZodEnum<["frontend", "backend", "meta-framework", "database", "orm", "auth", "hosting", "payments"]>>;
|
|
7
7
|
}, "strip", z.ZodTypeAny, {
|
|
8
|
-
category?: "
|
|
8
|
+
category?: "payments" | "database" | "meta-framework" | "frontend" | "orm" | "auth" | "hosting" | "backend" | undefined;
|
|
9
9
|
}, {
|
|
10
|
-
category?: "
|
|
10
|
+
category?: "payments" | "database" | "meta-framework" | "frontend" | "orm" | "auth" | "hosting" | "backend" | undefined;
|
|
11
11
|
}>;
|
|
12
12
|
export type ListTechsInput = z.infer<typeof ListTechsInputSchema>;
|
|
13
13
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksfinder/mcp-server",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "23 tools for deterministic tech stack recommendations, technology comparison, blueprint generation, technical debt audits, project estimation, MCP compatibility checking, and project kit. No hallucinations, just data.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,13 @@
|
|
|
14
14
|
"import": "./dist/index.js"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
|
-
"files": [
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
"CONTRIBUTING.md",
|
|
22
|
+
"SECURITY.md"
|
|
23
|
+
],
|
|
18
24
|
"scripts": {
|
|
19
25
|
"build": "tsc && npm run copy-data",
|
|
20
26
|
"copy-data": "node -e \"const fs=require('fs');['technology_scores.json','compatibility_matrix.json'].forEach(f=>fs.copyFileSync('src/data/'+f,'dist/data/'+f))\"",
|
|
@@ -37,11 +43,19 @@
|
|
|
37
43
|
"keywords": [
|
|
38
44
|
"mcp",
|
|
39
45
|
"model-context-protocol",
|
|
46
|
+
"anthropic",
|
|
40
47
|
"stacksfinder",
|
|
41
48
|
"tech-stack",
|
|
42
49
|
"llm",
|
|
43
50
|
"claude",
|
|
44
|
-
"cursor"
|
|
51
|
+
"cursor",
|
|
52
|
+
"windsurf",
|
|
53
|
+
"vscode",
|
|
54
|
+
"developer-tools",
|
|
55
|
+
"ai-assistant",
|
|
56
|
+
"code-assistant",
|
|
57
|
+
"blueprint",
|
|
58
|
+
"architecture"
|
|
45
59
|
],
|
|
46
60
|
"repository": {
|
|
47
61
|
"type": "git",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mcp-tools.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Server Integration Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests all 21 MCP tools to ensure they are functional.
|
|
5
|
-
* Run with: npm test or vitest
|
|
6
|
-
*/
|
|
7
|
-
import { describe, test, expect, beforeAll } from 'vitest';
|
|
8
|
-
import { createServer } from '../server.js';
|
|
9
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
10
|
-
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
11
|
-
import { ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
-
// ============================================================================
|
|
13
|
-
// TEST SETUP
|
|
14
|
-
// ============================================================================
|
|
15
|
-
// Helper to extract text from tool result
|
|
16
|
-
function getResultText(result) {
|
|
17
|
-
const content = result.content;
|
|
18
|
-
const textContent = content.find((c) => c.type === 'text');
|
|
19
|
-
return textContent?.text || '';
|
|
20
|
-
}
|
|
21
|
-
let client;
|
|
22
|
-
let server;
|
|
23
|
-
beforeAll(async () => {
|
|
24
|
-
server = createServer();
|
|
25
|
-
client = new Client({ name: 'test-client', version: '1.0.0' });
|
|
26
|
-
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
27
|
-
await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]);
|
|
28
|
-
});
|
|
29
|
-
// ============================================================================
|
|
30
|
-
// TOOL DISCOVERY TESTS
|
|
31
|
-
// ============================================================================
|
|
32
|
-
describe('MCP Server Tool Discovery', () => {
|
|
33
|
-
test('should list all 21 registered tools', async () => {
|
|
34
|
-
const result = await client.request({ method: 'tools/list' }, ListToolsResultSchema);
|
|
35
|
-
expect(result.tools).toBeDefined();
|
|
36
|
-
expect(result.tools.length).toBe(21);
|
|
37
|
-
const toolNames = result.tools.map((t) => t.name);
|
|
38
|
-
expect(toolNames).toContain('list_technologies');
|
|
39
|
-
expect(toolNames).toContain('analyze_tech');
|
|
40
|
-
expect(toolNames).toContain('compare_techs');
|
|
41
|
-
expect(toolNames).toContain('recommend_stack_demo');
|
|
42
|
-
expect(toolNames).toContain('recommend_stack');
|
|
43
|
-
expect(toolNames).toContain('get_blueprint');
|
|
44
|
-
expect(toolNames).toContain('create_blueprint');
|
|
45
|
-
expect(toolNames).toContain('setup_api_key');
|
|
46
|
-
expect(toolNames).toContain('list_api_keys');
|
|
47
|
-
expect(toolNames).toContain('revoke_api_key');
|
|
48
|
-
expect(toolNames).toContain('create_audit');
|
|
49
|
-
expect(toolNames).toContain('get_audit');
|
|
50
|
-
expect(toolNames).toContain('list_audits');
|
|
51
|
-
expect(toolNames).toContain('compare_audits');
|
|
52
|
-
expect(toolNames).toContain('get_audit_quota');
|
|
53
|
-
expect(toolNames).toContain('get_migration_recommendation');
|
|
54
|
-
expect(toolNames).toContain('generate_mcp_kit');
|
|
55
|
-
expect(toolNames).toContain('analyze_repo_mcps');
|
|
56
|
-
expect(toolNames).toContain('prepare_mcp_installation');
|
|
57
|
-
expect(toolNames).toContain('execute_mcp_installation');
|
|
58
|
-
expect(toolNames).toContain('check_mcp_compatibility');
|
|
59
|
-
});
|
|
60
|
-
test('all tools should have annotations', async () => {
|
|
61
|
-
const result = await client.request({ method: 'tools/list' }, ListToolsResultSchema);
|
|
62
|
-
for (const tool of result.tools) {
|
|
63
|
-
expect(tool.annotations).toBeDefined();
|
|
64
|
-
expect(tool.annotations?.readOnlyHint).toBeDefined();
|
|
65
|
-
expect(tool.annotations?.openWorldHint).toBeDefined();
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
test('local tools should have openWorldHint=false', async () => {
|
|
69
|
-
const result = await client.request({ method: 'tools/list' }, ListToolsResultSchema);
|
|
70
|
-
const localTools = [
|
|
71
|
-
'list_technologies',
|
|
72
|
-
'analyze_tech',
|
|
73
|
-
'compare_techs',
|
|
74
|
-
'recommend_stack_demo',
|
|
75
|
-
'generate_mcp_kit',
|
|
76
|
-
'check_mcp_compatibility',
|
|
77
|
-
'analyze_repo_mcps',
|
|
78
|
-
'execute_mcp_installation'
|
|
79
|
-
];
|
|
80
|
-
for (const toolName of localTools) {
|
|
81
|
-
const tool = result.tools.find((t) => t.name === toolName);
|
|
82
|
-
expect(tool).toBeDefined();
|
|
83
|
-
expect(tool?.annotations?.openWorldHint).toBe(false);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
test('API tools should have openWorldHint=true', async () => {
|
|
87
|
-
const result = await client.request({ method: 'tools/list' }, ListToolsResultSchema);
|
|
88
|
-
const apiTools = [
|
|
89
|
-
'recommend_stack',
|
|
90
|
-
'get_blueprint',
|
|
91
|
-
'create_blueprint',
|
|
92
|
-
'setup_api_key',
|
|
93
|
-
'list_api_keys',
|
|
94
|
-
'revoke_api_key',
|
|
95
|
-
'create_audit',
|
|
96
|
-
'get_audit',
|
|
97
|
-
'list_audits',
|
|
98
|
-
'compare_audits',
|
|
99
|
-
'get_audit_quota',
|
|
100
|
-
'get_migration_recommendation'
|
|
101
|
-
];
|
|
102
|
-
for (const toolName of apiTools) {
|
|
103
|
-
const tool = result.tools.find((t) => t.name === toolName);
|
|
104
|
-
expect(tool).toBeDefined();
|
|
105
|
-
expect(tool?.annotations?.openWorldHint).toBe(true);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
// ============================================================================
|
|
110
|
-
// LOCAL TOOL TESTS (no API key required)
|
|
111
|
-
// ============================================================================
|
|
112
|
-
describe('Local Tools (No API Key)', () => {
|
|
113
|
-
test('list_technologies should return technologies', async () => {
|
|
114
|
-
const result = (await client.callTool({
|
|
115
|
-
name: 'list_technologies',
|
|
116
|
-
arguments: {}
|
|
117
|
-
}));
|
|
118
|
-
expect(result.content).toBeDefined();
|
|
119
|
-
const text = getResultText(result);
|
|
120
|
-
expect(text).toContain('Technologies');
|
|
121
|
-
expect(text).toContain('frontend');
|
|
122
|
-
});
|
|
123
|
-
test('list_technologies should filter by category', async () => {
|
|
124
|
-
const result = (await client.callTool({
|
|
125
|
-
name: 'list_technologies',
|
|
126
|
-
arguments: { category: 'database' }
|
|
127
|
-
}));
|
|
128
|
-
const text = getResultText(result);
|
|
129
|
-
expect(text).toContain('database');
|
|
130
|
-
});
|
|
131
|
-
test('analyze_tech should analyze nextjs', async () => {
|
|
132
|
-
const result = (await client.callTool({
|
|
133
|
-
name: 'analyze_tech',
|
|
134
|
-
arguments: { technology: 'nextjs' }
|
|
135
|
-
}));
|
|
136
|
-
const text = getResultText(result);
|
|
137
|
-
expect(text).toContain('Next.js');
|
|
138
|
-
expect(text).toContain('Score');
|
|
139
|
-
});
|
|
140
|
-
test('analyze_tech should return error for unknown tech', async () => {
|
|
141
|
-
const result = (await client.callTool({
|
|
142
|
-
name: 'analyze_tech',
|
|
143
|
-
arguments: { technology: 'unknown-tech-xyz' }
|
|
144
|
-
}));
|
|
145
|
-
expect(result.isError).toBe(true);
|
|
146
|
-
const text = getResultText(result);
|
|
147
|
-
expect(text).toContain('not found');
|
|
148
|
-
});
|
|
149
|
-
test('compare_techs should compare frameworks', async () => {
|
|
150
|
-
const result = (await client.callTool({
|
|
151
|
-
name: 'compare_techs',
|
|
152
|
-
arguments: { technologies: ['nextjs', 'sveltekit'] }
|
|
153
|
-
}));
|
|
154
|
-
const text = getResultText(result);
|
|
155
|
-
expect(text).toContain('Comparison');
|
|
156
|
-
expect(text).toContain('Next.js');
|
|
157
|
-
expect(text).toContain('SvelteKit');
|
|
158
|
-
});
|
|
159
|
-
test('compare_techs should handle different contexts', async () => {
|
|
160
|
-
const result = (await client.callTool({
|
|
161
|
-
name: 'compare_techs',
|
|
162
|
-
arguments: { technologies: ['postgresql', 'mysql'], context: 'enterprise' }
|
|
163
|
-
}));
|
|
164
|
-
const text = getResultText(result);
|
|
165
|
-
expect(text).toContain('enterprise');
|
|
166
|
-
});
|
|
167
|
-
test('recommend_stack_demo should return recommendations', async () => {
|
|
168
|
-
const result = (await client.callTool({
|
|
169
|
-
name: 'recommend_stack_demo',
|
|
170
|
-
arguments: { projectType: 'saas' }
|
|
171
|
-
}));
|
|
172
|
-
// May return rate limit error, that's fine
|
|
173
|
-
const text = getResultText(result);
|
|
174
|
-
expect(text.length).toBeGreaterThan(0);
|
|
175
|
-
});
|
|
176
|
-
test('generate_mcp_kit should generate recommendations', async () => {
|
|
177
|
-
const result = (await client.callTool({
|
|
178
|
-
name: 'generate_mcp_kit',
|
|
179
|
-
arguments: {
|
|
180
|
-
projectDescription: 'A SaaS application for managing customer subscriptions with Stripe payments, PostgreSQL database, and Next.js frontend'
|
|
181
|
-
}
|
|
182
|
-
}));
|
|
183
|
-
const text = getResultText(result);
|
|
184
|
-
const parsed = JSON.parse(text);
|
|
185
|
-
expect(parsed).toHaveProperty('detectedTechnologies');
|
|
186
|
-
expect(parsed).toHaveProperty('recommendedMcps');
|
|
187
|
-
});
|
|
188
|
-
test('check_mcp_compatibility should detect conflicts', async () => {
|
|
189
|
-
const result = (await client.callTool({
|
|
190
|
-
name: 'check_mcp_compatibility',
|
|
191
|
-
arguments: { mcps: ['supabase-mcp', 'neon-mcp'] }
|
|
192
|
-
}));
|
|
193
|
-
const text = getResultText(result);
|
|
194
|
-
expect(text.toLowerCase()).toContain('conflict');
|
|
195
|
-
});
|
|
196
|
-
test('check_mcp_compatibility should detect synergies', async () => {
|
|
197
|
-
const result = (await client.callTool({
|
|
198
|
-
name: 'check_mcp_compatibility',
|
|
199
|
-
arguments: { mcps: ['stripe-mcp', 'resend-mcp'] }
|
|
200
|
-
}));
|
|
201
|
-
const text = getResultText(result);
|
|
202
|
-
expect(text.toLowerCase()).toContain('synerg');
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
// ============================================================================
|
|
206
|
-
// API TOOL TESTS (require API key - test error handling)
|
|
207
|
-
// ============================================================================
|
|
208
|
-
describe('API Tools (Error Handling Without API Key)', () => {
|
|
209
|
-
test('recommend_stack should require API key', async () => {
|
|
210
|
-
const result = (await client.callTool({
|
|
211
|
-
name: 'recommend_stack',
|
|
212
|
-
arguments: { projectType: 'saas' }
|
|
213
|
-
}));
|
|
214
|
-
// Should fail without API key
|
|
215
|
-
expect(result.isError).toBe(true);
|
|
216
|
-
const text = getResultText(result);
|
|
217
|
-
expect(text.toLowerCase()).toMatch(/api.?key|auth|unauthorized/i);
|
|
218
|
-
});
|
|
219
|
-
test('get_blueprint should handle invalid UUID', async () => {
|
|
220
|
-
// This tests input validation
|
|
221
|
-
try {
|
|
222
|
-
await client.callTool({
|
|
223
|
-
name: 'get_blueprint',
|
|
224
|
-
arguments: { blueprintId: 'not-a-uuid' }
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
catch (error) {
|
|
228
|
-
// Expected to fail validation
|
|
229
|
-
expect(error).toBeDefined();
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
test('list_api_keys should require API key', async () => {
|
|
233
|
-
const result = (await client.callTool({
|
|
234
|
-
name: 'list_api_keys',
|
|
235
|
-
arguments: {}
|
|
236
|
-
}));
|
|
237
|
-
expect(result.isError).toBe(true);
|
|
238
|
-
});
|
|
239
|
-
test('get_audit_quota should require API key', async () => {
|
|
240
|
-
const result = (await client.callTool({
|
|
241
|
-
name: 'get_audit_quota',
|
|
242
|
-
arguments: {}
|
|
243
|
-
}));
|
|
244
|
-
expect(result.isError).toBe(true);
|
|
245
|
-
});
|
|
246
|
-
test('create_audit should require API key', async () => {
|
|
247
|
-
const result = (await client.callTool({
|
|
248
|
-
name: 'create_audit',
|
|
249
|
-
arguments: {
|
|
250
|
-
name: 'Test Audit',
|
|
251
|
-
technologies: [{ name: 'React', version: '18.0.0' }]
|
|
252
|
-
}
|
|
253
|
-
}));
|
|
254
|
-
expect(result.isError).toBe(true);
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
// ============================================================================
|
|
258
|
-
// INPUT VALIDATION TESTS
|
|
259
|
-
// ============================================================================
|
|
260
|
-
describe('Input Validation', () => {
|
|
261
|
-
test('analyze_tech should require technology parameter', async () => {
|
|
262
|
-
try {
|
|
263
|
-
await client.callTool({
|
|
264
|
-
name: 'analyze_tech',
|
|
265
|
-
arguments: {}
|
|
266
|
-
});
|
|
267
|
-
expect(true).toBe(false); // Should not reach here
|
|
268
|
-
}
|
|
269
|
-
catch (error) {
|
|
270
|
-
expect(error).toBeDefined();
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
test('compare_techs should require at least 2 technologies', async () => {
|
|
274
|
-
try {
|
|
275
|
-
await client.callTool({
|
|
276
|
-
name: 'compare_techs',
|
|
277
|
-
arguments: { technologies: ['nextjs'] }
|
|
278
|
-
});
|
|
279
|
-
expect(true).toBe(false);
|
|
280
|
-
}
|
|
281
|
-
catch (error) {
|
|
282
|
-
expect(error).toBeDefined();
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
test('compare_techs should reject more than 4 technologies', async () => {
|
|
286
|
-
try {
|
|
287
|
-
await client.callTool({
|
|
288
|
-
name: 'compare_techs',
|
|
289
|
-
arguments: { technologies: ['nextjs', 'sveltekit', 'remix', 'nuxt', 'astro'] }
|
|
290
|
-
});
|
|
291
|
-
expect(true).toBe(false);
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
expect(error).toBeDefined();
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
test('generate_mcp_kit should require minimum description length', async () => {
|
|
298
|
-
try {
|
|
299
|
-
await client.callTool({
|
|
300
|
-
name: 'generate_mcp_kit',
|
|
301
|
-
arguments: { projectDescription: 'Too short' }
|
|
302
|
-
});
|
|
303
|
-
expect(true).toBe(false);
|
|
304
|
-
}
|
|
305
|
-
catch (error) {
|
|
306
|
-
expect(error).toBeDefined();
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
test('check_mcp_compatibility should require at least 1 MCP', async () => {
|
|
310
|
-
try {
|
|
311
|
-
await client.callTool({
|
|
312
|
-
name: 'check_mcp_compatibility',
|
|
313
|
-
arguments: { mcps: [] }
|
|
314
|
-
});
|
|
315
|
-
expect(true).toBe(false);
|
|
316
|
-
}
|
|
317
|
-
catch (error) {
|
|
318
|
-
expect(error).toBeDefined();
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
// ============================================================================
|
|
323
|
-
// PROJECT-KIT TOOL TESTS
|
|
324
|
-
// ============================================================================
|
|
325
|
-
describe('Project-Kit Tools', () => {
|
|
326
|
-
test('analyze_repo_mcps should work without workspace', async () => {
|
|
327
|
-
const result = (await client.callTool({
|
|
328
|
-
name: 'analyze_repo_mcps',
|
|
329
|
-
arguments: { workspaceRoot: '/nonexistent/path' }
|
|
330
|
-
}));
|
|
331
|
-
// Should return empty analysis, not error
|
|
332
|
-
const text = getResultText(result);
|
|
333
|
-
expect(text).toContain('Repository Analysis');
|
|
334
|
-
});
|
|
335
|
-
test('execute_mcp_installation should handle missing .env-mcp', async () => {
|
|
336
|
-
const result = (await client.callTool({
|
|
337
|
-
name: 'execute_mcp_installation',
|
|
338
|
-
arguments: { envMcpPath: '/nonexistent/.env-mcp' }
|
|
339
|
-
}));
|
|
340
|
-
const text = getResultText(result);
|
|
341
|
-
// Should handle gracefully
|
|
342
|
-
expect(text.length).toBeGreaterThan(0);
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
//# sourceMappingURL=mcp-tools.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/mcp-tools.test.ts"],"names":[],"mappings":"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"}
|