@stackguide/mcp-server 1.0.2 → 1.1.1

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/README.md CHANGED
@@ -32,48 +32,57 @@ Dynamic context loading for AI coding assistants. Works with **Cursor** and **Gi
32
32
 
33
33
  ### 2. Use
34
34
 
35
- Just ask your AI assistant:
36
- - *"Select project type react-node"*
37
- - *"List available rules"*
38
- - *"Get full context"*
39
- - *"Browse cursor directory for python rules"*
35
+ Just tell your AI assistant in natural language:
36
+
37
+ - *"Set up my project"* → Auto-detects and configures everything
38
+ - *"I'm working on a Django API"* → Configures Python/Django context
39
+ - *"Configure for React with TypeScript"* → Sets up React-TS rules
40
+ - *"Browse Python rules from cursor directory"* → Shows community rules
41
+
42
+ ## Auto-Setup (NEW in 1.1.0!)
43
+
44
+ StackGuide can automatically detect your project type and configure itself:
45
+
46
+ ```
47
+ auto_setup projectPath:"."
48
+ ```
49
+
50
+ It analyzes your `package.json`, `requirements.txt`, `Cargo.toml`, etc. and loads the right rules.
40
51
 
41
52
  ## Supported Stacks
42
53
 
43
54
  `python-django` · `python-fastapi` · `python-flask` · `react-node` · `react-typescript` · `vue-node` · `nextjs` · `express` · `nestjs` · `laravel` · `rails` · `golang` · `rust`
44
55
 
45
- ## Tools (42 total)
56
+ ## Tools (46 total)
46
57
 
47
58
  | Category | Tools |
48
59
  |----------|-------|
60
+ | **Smart Setup** | `auto_setup` `detect_project` `suggest_rules` `quick_start` |
49
61
  | **Project** | `list_project_types` `select_project_type` `get_current_context` |
50
62
  | **Rules** | `list_rules` `get_rule` `select_rules` `search_rules` `create_rule` `update_rule` `delete_rule` |
51
63
  | **Knowledge** | `list_knowledge` `get_knowledge` `select_knowledge` `search_knowledge` |
52
64
  | **Config** | `save_configuration` `load_configuration` `list_configurations` `export_configuration` |
53
65
  | **Web Docs** | `fetch_web_docs` `list_web_docs` `search_web_docs` `get_suggested_docs` |
54
- | **Cursor Directory** | `browse_cursor_directory` `search_cursor_directory` `import_cursor_directory_rule` `get_popular_cursor_rules` |
66
+ | **Cursor Directory** | `browse_cursor_directory` `search_cursor_directory` `import_cursor_directory_rule` |
55
67
  | **Context** | `get_full_context` `add_custom_rule` |
56
68
 
69
+ ## How It Works
70
+
71
+ 1. **Auto-detect**: Analyzes project files to identify your stack
72
+ 2. **Load context**: Loads relevant rules, standards, and patterns
73
+ 3. **Suggest**: Recommends community rules from cursor.directory
74
+ 4. **Persist**: Saves your configuration for future sessions
75
+
57
76
  ## Cursor Directory Integration
58
77
 
59
78
  Import community rules from [cursor.directory](https://cursor.directory/rules/):
60
79
 
61
80
  ```
62
81
  browse_cursor_directory category:"python"
63
- search_cursor_directory query:"react best practices"
82
+ search_cursor_directory query:"react hooks"
64
83
  import_cursor_directory_rule slug:"nextjs-react-typescript-cursor-rules"
65
84
  ```
66
85
 
67
- ## Custom Rules
68
-
69
- Create your own rules that persist across sessions:
70
-
71
- ```
72
- create_rule projectType:"react-node" name:"My Standards" category:"best-practices" content:"..."
73
- ```
74
-
75
- Rules are stored in `~/.stackguide/rules/`.
76
-
77
86
  ## License
78
87
 
79
88
  GPL-3.0
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import * as knowledgeProvider from './resources/knowledgeProvider.js';
9
9
  import * as ruleManager from './services/ruleManager.js';
10
10
  import * as webDocs from './services/webDocumentation.js';
11
11
  import * as cursorDirectory from './services/cursorDirectory.js';
12
+ import * as autoDetect from './services/autoDetect.js';
12
13
  // Server state
13
14
  const serverState = {
14
15
  activeProjectType: null,
@@ -19,7 +20,7 @@ const serverState = {
19
20
  // Create MCP server
20
21
  const server = new Server({
21
22
  name: 'stackguide-mcp',
22
- version: '1.0.0',
23
+ version: '1.1.0',
23
24
  }, {
24
25
  capabilities: {
25
26
  tools: {},
@@ -31,6 +32,64 @@ const server = new Server({
31
32
  server.setRequestHandler(ListToolsRequestSchema, async () => {
32
33
  return {
33
34
  tools: [
35
+ // Smart Setup Tools (NEW!)
36
+ {
37
+ name: 'auto_setup',
38
+ description: 'Automatically detect your project type, configure context, and suggest rules. Just provide your project path and StackGuide will do the rest!',
39
+ inputSchema: {
40
+ type: 'object',
41
+ properties: {
42
+ projectPath: {
43
+ type: 'string',
44
+ description: 'Path to your project directory. Use "." for current directory.'
45
+ }
46
+ },
47
+ required: ['projectPath']
48
+ }
49
+ },
50
+ {
51
+ name: 'detect_project',
52
+ description: 'Analyze a project directory to detect the framework, languages, and suggest the best configuration',
53
+ inputSchema: {
54
+ type: 'object',
55
+ properties: {
56
+ projectPath: {
57
+ type: 'string',
58
+ description: 'Path to your project directory'
59
+ }
60
+ },
61
+ required: ['projectPath']
62
+ }
63
+ },
64
+ {
65
+ name: 'suggest_rules',
66
+ description: 'Get personalized rule suggestions based on your project type and current setup',
67
+ inputSchema: {
68
+ type: 'object',
69
+ properties: {
70
+ projectType: {
71
+ type: 'string',
72
+ description: 'Project type to get suggestions for',
73
+ enum: Object.keys(SUPPORTED_PROJECTS)
74
+ }
75
+ },
76
+ required: []
77
+ }
78
+ },
79
+ {
80
+ name: 'quick_start',
81
+ description: 'Get a quick start guide for your detected or selected project type. Perfect for new users!',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ projectPath: {
86
+ type: 'string',
87
+ description: 'Path to analyze (optional if project type already selected)'
88
+ }
89
+ },
90
+ required: []
91
+ }
92
+ },
34
93
  // Project Type Tools
35
94
  {
36
95
  name: 'list_project_types',
@@ -708,6 +767,174 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
708
767
  const { name, arguments: args } = request.params;
709
768
  try {
710
769
  switch (name) {
770
+ // Smart Setup Tools
771
+ case 'auto_setup': {
772
+ const { projectPath } = args;
773
+ const resolvedPath = projectPath === '.' ? process.cwd() : projectPath;
774
+ // Detect project
775
+ const detection = autoDetect.detectProjectType(resolvedPath);
776
+ if (!detection.detected || !detection.projectType) {
777
+ return {
778
+ content: [{
779
+ type: 'text',
780
+ text: JSON.stringify({
781
+ success: false,
782
+ message: 'Could not auto-detect project type',
783
+ hint: 'Please use select_project_type to manually choose your project type',
784
+ availableTypes: Object.keys(SUPPORTED_PROJECTS)
785
+ }, null, 2)
786
+ }]
787
+ };
788
+ }
789
+ // Auto-configure
790
+ const projectType = detection.projectType;
791
+ const project = SUPPORTED_PROJECTS[projectType];
792
+ serverState.activeProjectType = projectType;
793
+ serverState.loadedRules = rulesProvider.getRulesForProject(projectType);
794
+ serverState.loadedKnowledge = knowledgeProvider.getKnowledgeForProject(projectType);
795
+ // Create an active configuration with all rules/knowledge selected
796
+ serverState.activeConfiguration = {
797
+ id: `auto-${projectType}-${Date.now()}`,
798
+ name: `Auto Setup - ${project.name}`,
799
+ projectType: projectType,
800
+ selectedRules: serverState.loadedRules.map(r => r.id),
801
+ selectedKnowledge: serverState.loadedKnowledge.map(k => k.id),
802
+ customRules: [],
803
+ createdAt: new Date().toISOString(),
804
+ updatedAt: new Date().toISOString()
805
+ };
806
+ const setupInstructions = autoDetect.getSetupInstructions(projectType);
807
+ return {
808
+ content: [{
809
+ type: 'text',
810
+ text: JSON.stringify({
811
+ success: true,
812
+ message: `✅ Auto-configured for ${project.name}`,
813
+ detection: {
814
+ projectType: detection.projectType,
815
+ confidence: detection.confidence,
816
+ languages: detection.languages,
817
+ frameworks: detection.frameworks,
818
+ indicators: detection.indicators
819
+ },
820
+ configured: {
821
+ rulesLoaded: serverState.loadedRules.length,
822
+ knowledgeLoaded: serverState.loadedKnowledge.length,
823
+ rules: serverState.loadedRules.map(r => r.name)
824
+ },
825
+ suggestions: detection.suggestions.slice(0, 5),
826
+ nextSteps: [
827
+ 'Use get_full_context to see all loaded rules',
828
+ 'Use browse_cursor_directory to find community rules',
829
+ 'Use save_configuration to save this setup'
830
+ ],
831
+ setupGuide: setupInstructions
832
+ }, null, 2)
833
+ }]
834
+ };
835
+ }
836
+ case 'detect_project': {
837
+ const { projectPath } = args;
838
+ const resolvedPath = projectPath === '.' ? process.cwd() : projectPath;
839
+ const detection = autoDetect.detectProjectType(resolvedPath);
840
+ const quickStart = autoDetect.generateQuickStart(detection);
841
+ return {
842
+ content: [{
843
+ type: 'text',
844
+ text: JSON.stringify({
845
+ ...detection,
846
+ quickStart
847
+ }, null, 2)
848
+ }]
849
+ };
850
+ }
851
+ case 'suggest_rules': {
852
+ const { projectType } = args;
853
+ const pt = projectType || serverState.activeProjectType;
854
+ if (!pt) {
855
+ return {
856
+ content: [{
857
+ type: 'text',
858
+ text: JSON.stringify({
859
+ error: 'No project type specified or selected',
860
+ hint: 'Use auto_setup or select_project_type first, or provide projectType parameter'
861
+ }, null, 2)
862
+ }]
863
+ };
864
+ }
865
+ const suggestions = autoDetect.getSuggestions(pt);
866
+ const builtInRules = rulesProvider.getRulesForProject(pt);
867
+ const cursorCategories = cursorDirectory.getCursorDirectoryCategories()
868
+ .filter(cat => pt.toLowerCase().includes(cat) || cat.includes(pt.split('-')[0]));
869
+ return {
870
+ content: [{
871
+ type: 'text',
872
+ text: JSON.stringify({
873
+ projectType: pt,
874
+ suggestions: suggestions,
875
+ builtInRules: builtInRules.map(r => ({ id: r.id, name: r.name, category: r.category })),
876
+ recommendedCursorCategories: cursorCategories.length > 0 ? cursorCategories : ['Check browse_cursor_directory for all categories'],
877
+ tips: [
878
+ 'Use browse_cursor_directory to import community rules',
879
+ 'Use create_rule to add your own custom rules',
880
+ 'Use save_configuration to persist your setup'
881
+ ]
882
+ }, null, 2)
883
+ }]
884
+ };
885
+ }
886
+ case 'quick_start': {
887
+ const { projectPath } = args;
888
+ let detection = null;
889
+ if (projectPath) {
890
+ const resolvedPath = projectPath === '.' ? process.cwd() : projectPath;
891
+ detection = autoDetect.detectProjectType(resolvedPath);
892
+ }
893
+ else if (serverState.activeProjectType) {
894
+ // Create a pseudo-detection from active state
895
+ detection = {
896
+ detected: true,
897
+ projectType: serverState.activeProjectType,
898
+ confidence: 'high',
899
+ indicators: ['Already configured'],
900
+ suggestions: autoDetect.getSuggestions(serverState.activeProjectType),
901
+ frameworks: SUPPORTED_PROJECTS[serverState.activeProjectType]?.frameworks || [],
902
+ languages: SUPPORTED_PROJECTS[serverState.activeProjectType]?.languages || []
903
+ };
904
+ }
905
+ if (!detection) {
906
+ return {
907
+ content: [{
908
+ type: 'text',
909
+ text: `# StackGuide Quick Start
910
+
911
+ Welcome! Let's get you set up.
912
+
913
+ ## Option 1: Auto-detect (Recommended)
914
+ \`\`\`
915
+ auto_setup projectPath:"."
916
+ \`\`\`
917
+
918
+ ## Option 2: Manual selection
919
+ \`\`\`
920
+ select_project_type projectType:"react-node"
921
+ \`\`\`
922
+
923
+ ## Available project types:
924
+ ${Object.values(SUPPORTED_PROJECTS).map(p => `- **${p.type}**: ${p.name}`).join('\n')}
925
+
926
+ Just tell me about your project and I'll help you configure!`
927
+ }]
928
+ };
929
+ }
930
+ const quickStart = autoDetect.generateQuickStart(detection);
931
+ return {
932
+ content: [{
933
+ type: 'text',
934
+ text: quickStart
935
+ }]
936
+ };
937
+ }
711
938
  // Project Type Tools
712
939
  case 'list_project_types': {
713
940
  const projects = Object.values(SUPPORTED_PROJECTS).map(p => ({
@@ -728,6 +955,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
728
955
  serverState.activeProjectType = projectType;
729
956
  serverState.loadedRules = rulesProvider.getRulesForProject(projectType);
730
957
  serverState.loadedKnowledge = knowledgeProvider.getKnowledgeForProject(projectType);
958
+ // Create an active configuration with all rules/knowledge selected
959
+ serverState.activeConfiguration = {
960
+ id: `manual-${projectType}-${Date.now()}`,
961
+ name: `Manual Setup - ${project.name}`,
962
+ projectType: projectType,
963
+ selectedRules: serverState.loadedRules.map(r => r.id),
964
+ selectedKnowledge: serverState.loadedKnowledge.map(k => k.id),
965
+ customRules: [],
966
+ createdAt: new Date().toISOString(),
967
+ updatedAt: new Date().toISOString()
968
+ };
731
969
  return {
732
970
  content: [{
733
971
  type: 'text',
@@ -735,7 +973,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
735
973
  success: true,
736
974
  message: `Project type "${project.name}" activated`,
737
975
  rulesLoaded: serverState.loadedRules.length,
738
- knowledgeLoaded: serverState.loadedKnowledge.length
976
+ knowledgeLoaded: serverState.loadedKnowledge.length,
977
+ rules: serverState.loadedRules.map(r => r.name)
739
978
  }, null, 2)
740
979
  }]
741
980
  };
@@ -988,23 +1227,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
988
1227
  // Context Tools
989
1228
  case 'get_full_context': {
990
1229
  if (!serverState.activeProjectType) {
991
- return { content: [{ type: 'text', text: 'Error: No project type selected.' }] };
992
- }
993
- const selectedRules = serverState.activeConfiguration?.selectedRules || [];
994
- const selectedKnowledge = serverState.activeConfiguration?.selectedKnowledge || [];
1230
+ return { content: [{ type: 'text', text: 'Error: No project type selected. Use auto_setup or select_project_type first.' }] };
1231
+ }
1232
+ // Use configuration selection if available, otherwise use all loaded rules/knowledge
1233
+ const selectedRules = serverState.activeConfiguration?.selectedRules ||
1234
+ serverState.loadedRules.map(r => r.id);
1235
+ const selectedKnowledge = serverState.activeConfiguration?.selectedKnowledge ||
1236
+ serverState.loadedKnowledge.map(k => k.id);
1237
+ // Also get user-created rules for this project type
1238
+ const userRules = ruleManager.getUserRules(serverState.activeProjectType);
1239
+ const userRulesContent = userRules.map((r) => `### ${r.name}\n\n${r.content}`).join('\n\n---\n\n');
995
1240
  const rulesContent = rulesProvider.getCombinedRulesContent(selectedRules);
996
1241
  const knowledgeContent = knowledgeProvider.getCombinedKnowledgeContent(selectedKnowledge);
997
1242
  const fullContext = `# Project Context: ${SUPPORTED_PROJECTS[serverState.activeProjectType].name}
998
1243
 
999
- ## Rules and Guidelines
1244
+ ## Rules and Guidelines (${selectedRules.length} loaded)
1000
1245
 
1001
- ${rulesContent || 'No rules selected.'}
1246
+ ${rulesContent || 'No rules available.'}
1247
+
1248
+ ${userRulesContent ? `---\n\n## Custom Rules\n\n${userRulesContent}` : ''}
1002
1249
 
1003
1250
  ---
1004
1251
 
1005
- ## Knowledge Base
1252
+ ## Knowledge Base (${selectedKnowledge.length} loaded)
1006
1253
 
1007
- ${knowledgeContent || 'No knowledge files selected.'}
1254
+ ${knowledgeContent || 'No knowledge files available.'}
1008
1255
  `;
1009
1256
  return { content: [{ type: 'text', text: fullContext }] };
1010
1257
  }
@@ -1633,6 +1880,22 @@ ${webDocsContent || 'No web documentation loaded.'}
1633
1880
  server.setRequestHandler(ListPromptsRequestSchema, async () => {
1634
1881
  return {
1635
1882
  prompts: [
1883
+ {
1884
+ name: 'welcome',
1885
+ description: 'Get started with StackGuide - interactive setup wizard',
1886
+ arguments: []
1887
+ },
1888
+ {
1889
+ name: 'configure_project',
1890
+ description: 'Smart project configuration with auto-detection and suggestions',
1891
+ arguments: [
1892
+ {
1893
+ name: 'projectPath',
1894
+ description: 'Path to your project (use "." for current directory)',
1895
+ required: false
1896
+ }
1897
+ ]
1898
+ },
1636
1899
  {
1637
1900
  name: 'setup_project',
1638
1901
  description: 'Initialize context for a new project',
@@ -1672,6 +1935,110 @@ server.setRequestHandler(ListPromptsRequestSchema, async () => {
1672
1935
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1673
1936
  const { name, arguments: promptArgs } = request.params;
1674
1937
  switch (name) {
1938
+ case 'welcome': {
1939
+ const projectTypes = Object.values(SUPPORTED_PROJECTS)
1940
+ .map(p => `- **${p.type}**: ${p.name} (${p.languages.join(', ')})`)
1941
+ .join('\n');
1942
+ return {
1943
+ messages: [{
1944
+ role: 'user',
1945
+ content: {
1946
+ type: 'text',
1947
+ text: `# Welcome to StackGuide! 👋
1948
+
1949
+ I'm your AI coding context manager. I help you load the right rules, standards, and knowledge for your project.
1950
+
1951
+ ## Quick Start
1952
+
1953
+ **Option 1: Auto-detect (Recommended)**
1954
+ Just tell me: "Set up my project" and I'll analyze your codebase and configure everything automatically.
1955
+
1956
+ **Option 2: Tell me about your project**
1957
+ Say something like:
1958
+ - "I'm working on a React app with Node.js backend"
1959
+ - "This is a Django REST API project"
1960
+ - "Configure for Next.js with TypeScript"
1961
+
1962
+ ## Supported Project Types
1963
+ ${projectTypes}
1964
+
1965
+ ## What I Can Do
1966
+ - 📋 Load coding standards and best practices for your stack
1967
+ - 🔍 Browse and import rules from cursor.directory
1968
+ - 📚 Provide architecture patterns and solutions
1969
+ - 💾 Save configurations for your projects
1970
+ - 🌐 Fetch and cache documentation from any URL
1971
+
1972
+ ## Ready?
1973
+ Just describe your project and I'll configure everything for you!`
1974
+ }
1975
+ }]
1976
+ };
1977
+ }
1978
+ case 'configure_project': {
1979
+ const projectPath = promptArgs?.projectPath || '.';
1980
+ const resolvedPath = projectPath === '.' ? process.cwd() : projectPath;
1981
+ let detection = null;
1982
+ try {
1983
+ detection = autoDetect.detectProjectType(resolvedPath);
1984
+ }
1985
+ catch {
1986
+ // Path might not exist or not accessible
1987
+ }
1988
+ if (detection?.detected && detection.projectType) {
1989
+ const suggestions = detection.suggestions.slice(0, 5);
1990
+ return {
1991
+ messages: [{
1992
+ role: 'user',
1993
+ content: {
1994
+ type: 'text',
1995
+ text: `# Project Detected! 🎯
1996
+
1997
+ **Type**: ${detection.projectType}
1998
+ **Confidence**: ${detection.confidence}
1999
+ **Languages**: ${detection.languages.join(', ')}
2000
+ **Frameworks**: ${detection.frameworks.join(', ')}
2001
+
2002
+ ## How I detected this:
2003
+ ${detection.indicators.map(i => `- ${i}`).join('\n')}
2004
+
2005
+ ## Recommended Setup
2006
+
2007
+ ### Suggested Rules:
2008
+ ${suggestions.map(s => `- ${s}`).join('\n')}
2009
+
2010
+ ### Next Steps:
2011
+ 1. Run \`auto_setup projectPath:"${projectPath}"\` to configure automatically
2012
+ 2. Or run \`select_project_type projectType:"${detection.projectType}"\` to activate manually
2013
+ 3. Browse community rules: \`browse_cursor_directory category:"${detection.projectType.split('-')[0]}"\`
2014
+
2015
+ Would you like me to set this up for you?`
2016
+ }
2017
+ }]
2018
+ };
2019
+ }
2020
+ return {
2021
+ messages: [{
2022
+ role: 'user',
2023
+ content: {
2024
+ type: 'text',
2025
+ text: `# Let's Configure Your Project 🔧
2026
+
2027
+ I couldn't auto-detect the project type from the path provided.
2028
+
2029
+ ## Tell me about your project:
2030
+ - What framework are you using? (React, Django, Next.js, etc.)
2031
+ - What language? (TypeScript, Python, etc.)
2032
+ - Is it a full-stack app, API, or frontend-only?
2033
+
2034
+ ## Or choose from available types:
2035
+ ${Object.values(SUPPORTED_PROJECTS).map(p => `- **${p.type}**: ${p.name}`).join('\n')}
2036
+
2037
+ Just tell me and I'll set everything up!`
2038
+ }
2039
+ }]
2040
+ };
2041
+ }
1675
2042
  case 'setup_project': {
1676
2043
  const projectType = promptArgs?.projectType;
1677
2044
  const project = SUPPORTED_PROJECTS[projectType];