@stackguide/mcp-server 1.0.0

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.
Files changed (48) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +453 -0
  3. package/data/knowledge/python-django/architecture/architecture-patterns.md +201 -0
  4. package/data/knowledge/python-django/common-issues/common-issues.md +181 -0
  5. package/data/knowledge/python-django/patterns/drf-patterns.md +133 -0
  6. package/data/knowledge/react-node/architecture/node-architecture.md +257 -0
  7. package/data/knowledge/react-node/common-issues/common-issues.md +262 -0
  8. package/data/knowledge/react-node/patterns/react-patterns.md +244 -0
  9. package/data/rules/python-django/best-practices/django-best-practices.md +120 -0
  10. package/data/rules/python-django/coding-standards/django-standards.md +104 -0
  11. package/data/rules/python-django/security/security-guidelines.md +146 -0
  12. package/data/rules/react-node/best-practices/react-best-practices.md +195 -0
  13. package/data/rules/react-node/coding-standards/node-standards.md +192 -0
  14. package/data/rules/react-node/coding-standards/react-standards.md +155 -0
  15. package/data/rules/react-node/security/security-guidelines.md +228 -0
  16. package/dist/config/persistence.d.ts +15 -0
  17. package/dist/config/persistence.d.ts.map +1 -0
  18. package/dist/config/persistence.js +171 -0
  19. package/dist/config/persistence.js.map +1 -0
  20. package/dist/config/types.d.ts +47 -0
  21. package/dist/config/types.d.ts.map +1 -0
  22. package/dist/config/types.js +116 -0
  23. package/dist/config/types.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +1799 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/resources/knowledgeProvider.d.ts +10 -0
  29. package/dist/resources/knowledgeProvider.d.ts.map +1 -0
  30. package/dist/resources/knowledgeProvider.js +130 -0
  31. package/dist/resources/knowledgeProvider.js.map +1 -0
  32. package/dist/resources/rulesProvider.d.ts +10 -0
  33. package/dist/resources/rulesProvider.d.ts.map +1 -0
  34. package/dist/resources/rulesProvider.js +135 -0
  35. package/dist/resources/rulesProvider.js.map +1 -0
  36. package/dist/services/cursorDirectory.d.ts +55 -0
  37. package/dist/services/cursorDirectory.d.ts.map +1 -0
  38. package/dist/services/cursorDirectory.js +367 -0
  39. package/dist/services/cursorDirectory.js.map +1 -0
  40. package/dist/services/ruleManager.d.ts +18 -0
  41. package/dist/services/ruleManager.d.ts.map +1 -0
  42. package/dist/services/ruleManager.js +382 -0
  43. package/dist/services/ruleManager.js.map +1 -0
  44. package/dist/services/webDocumentation.d.ts +41 -0
  45. package/dist/services/webDocumentation.d.ts.map +1 -0
  46. package/dist/services/webDocumentation.js +237 -0
  47. package/dist/services/webDocumentation.js.map +1 -0
  48. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,453 @@
1
+ # StackGuide MCP Server
2
+
3
+ A Model Context Protocol (MCP) server that provides dynamic language and framework context for AI coding assistants. Compatible with **Cursor** and **GitHub Copilot**.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Dynamic Context Loading**: Load context based on your project type (Python/Django, React/Node, etc.)
8
+ - 📋 **Rules Management**: Select and apply coding standards, best practices, and security guidelines
9
+ - 📚 **Knowledge Base**: Access architecture patterns, common issues solutions, and code snippets
10
+ - 💾 **Configuration Persistence**: Save and load your preferred configurations
11
+ - 🔄 **Compatible**: Works with both Cursor and GitHub Copilot
12
+ - ✨ **Dynamic Rule Management**: Create, edit, and delete rules at runtime using tools
13
+ - 🌐 **Web Documentation**: Fetch and cache documentation from any URL
14
+ - 📝 **Rule Templates**: Quick-start templates for common rule types (coding-standard, best-practice, security, architecture, testing)
15
+ - 🔗 **Cursor Directory Integration**: Browse, search, and import rules from [cursor.directory](https://cursor.directory/rules/) - a community-driven repository of AI coding rules
16
+
17
+ ## Supported Project Types
18
+
19
+ | Type | Languages | Frameworks |
20
+ |------|-----------|------------|
21
+ | `python-django` | Python | Django, DRF |
22
+ | `python-fastapi` | Python | FastAPI |
23
+ | `python-flask` | Python | Flask |
24
+ | `react-node` | JavaScript, TypeScript | React, Node.js, Express |
25
+ | `react-typescript` | TypeScript | React |
26
+ | `vue-node` | JavaScript, TypeScript | Vue.js, Node.js |
27
+ | `nextjs` | JavaScript, TypeScript | Next.js, React |
28
+ | `express` | JavaScript, TypeScript | Express.js |
29
+ | `nestjs` | TypeScript | NestJS |
30
+ | `laravel` | PHP | Laravel |
31
+ | `rails` | Ruby | Ruby on Rails |
32
+ | `golang` | Go | - |
33
+ | `rust` | Rust | - |
34
+
35
+ ## Installation
36
+
37
+ ### From npm (Recommended)
38
+
39
+ ```bash
40
+ npm install -g @stackguide/mcp-server
41
+ ```
42
+
43
+ ### From Source
44
+
45
+ ```bash
46
+ git clone https://github.com/taimiralain/StackGuide-MCP.git
47
+ cd StackGuide-MCP
48
+ npm install
49
+ npm run build
50
+ ```
51
+
52
+ ## Configuration
53
+
54
+ ### For Cursor
55
+
56
+ Add to your Cursor settings (`.cursor/mcp.json`):
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "stackguide": {
62
+ "command": "npx",
63
+ "args": ["-y", "@stackguide/mcp-server"]
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ Or if installed from source:
70
+
71
+ ```json
72
+ {
73
+ "mcpServers": {
74
+ "stackguide": {
75
+ "command": "node",
76
+ "args": ["/path/to/StackGuide-MCP/dist/index.js"]
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### For VS Code with GitHub Copilot
83
+
84
+ Add to `.vscode/mcp.json` in your workspace:
85
+
86
+ ```json
87
+ {
88
+ "mcpServers": {
89
+ "stackguide": {
90
+ "command": "npx",
91
+ "args": ["-y", "@stackguide/mcp-server"]
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ Or add to your user settings (`settings.json`):
98
+
99
+ ```json
100
+ {
101
+ "github.copilot.chat.mcpServers": {
102
+ "stackguide": {
103
+ "command": "npx",
104
+ "args": ["-y", "@stackguide/mcp-server"]
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ## Usage
111
+
112
+ ### Available Tools
113
+
114
+ #### Project Type Management
115
+ - `list_project_types` - List all supported project types
116
+ - `select_project_type` - Activate a project type context
117
+ - `get_current_context` - Get the currently active context
118
+
119
+ #### Rules Management
120
+ - `list_rules` - List available rules for current project
121
+ - `get_rule` - Get full content of a specific rule
122
+ - `select_rules` - Select which rules to include in context
123
+ - `search_rules` - Search rules by keyword
124
+
125
+ #### Knowledge Base
126
+ - `list_knowledge` - List knowledge base files
127
+ - `get_knowledge` - Get content of a knowledge file
128
+ - `select_knowledge` - Select knowledge to include
129
+ - `search_knowledge` - Search knowledge base
130
+
131
+ #### Configuration
132
+ - `save_configuration` - Save current context setup
133
+ - `load_configuration` - Load a saved configuration
134
+ - `list_configurations` - List all saved configurations
135
+ - `delete_configuration` - Delete a configuration
136
+ - `export_configuration` - Export config as JSON
137
+ - `import_configuration` - Import config from JSON
138
+
139
+ #### Dynamic Rule Management (NEW!)
140
+ - `create_rule` - Create a new custom rule from scratch
141
+ - `create_rule_from_template` - Create a rule using a template
142
+ - `list_rule_templates` - List available rule templates
143
+ - `update_rule` - Update an existing user rule
144
+ - `delete_rule` - Delete a user rule
145
+ - `list_user_rules` - List all user-created rules
146
+ - `export_user_rules` - Export all user rules as JSON
147
+ - `import_user_rules` - Import user rules from JSON
148
+
149
+ #### Web Documentation (NEW!)
150
+ - `fetch_web_docs` - Fetch documentation from any URL
151
+ - `fetch_multiple_docs` - Fetch multiple URLs at once
152
+ - `get_web_doc` - Get a cached web document
153
+ - `search_web_docs` - Search cached documentation
154
+ - `list_web_docs` - List all cached documents
155
+ - `get_suggested_docs` - Get suggested docs for a project type
156
+ - `remove_web_doc` - Remove a cached document
157
+
158
+ #### Cursor Directory Integration (NEW!)
159
+ - `browse_cursor_directory` - Browse rules by category from cursor.directory
160
+ - `search_cursor_directory` - Search for rules on cursor.directory
161
+ - `get_cursor_directory_rule` - Get a specific rule by slug
162
+ - `list_cursor_directory_categories` - List all available categories
163
+ - `get_popular_cursor_rules` - Get popular/featured rules
164
+ - `import_cursor_directory_rule` - Import a rule into your local collection
165
+
166
+ #### Context
167
+ - `get_full_context` - Get complete active context
168
+ - `add_custom_rule` - Add a custom rule
169
+
170
+ ### Example Workflow
171
+
172
+ 1. **Select your project type:**
173
+ ```
174
+ Use select_project_type with "react-node"
175
+ ```
176
+
177
+ 2. **View available rules:**
178
+ ```
179
+ Use list_rules to see all available rules
180
+ ```
181
+
182
+ 3. **Select specific rules:**
183
+ ```
184
+ Use select_rules with the IDs of rules you want
185
+ ```
186
+
187
+ 4. **Save your configuration:**
188
+ ```
189
+ Use save_configuration with a name like "My React Setup"
190
+ ```
191
+
192
+ 5. **Get full context for AI:**
193
+ ```
194
+ Use get_full_context to get all selected rules and knowledge
195
+ ```
196
+
197
+ ### Available Resources
198
+
199
+ - `rules://{project_type}/all` - All rules for a project type
200
+ - `knowledge://{project_type}/all` - All knowledge for a project type
201
+ - `context://active` - Currently active context (includes rules, user rules, knowledge, and web docs)
202
+ - `user-rules://{project_type}/all` - All user-created rules for a project type
203
+ - `web-doc://{doc_id}` - Specific cached web document
204
+ - `templates://rules` - Available rule templates
205
+
206
+ ### Available Prompts
207
+
208
+ - `setup_project` - Initialize context for a new project
209
+ - `code_review` - Review code with active rules
210
+ - `apply_patterns` - Apply architecture patterns
211
+
212
+ ## Adding Custom Rules
213
+
214
+ ### Via Tool
215
+ Use the `add_custom_rule` tool with:
216
+ - `name`: Rule name
217
+ - `category`: One of `coding-standards`, `best-practices`, `security`, `performance`, `architecture`, `testing`, `documentation`, `naming-conventions`
218
+ - `content`: Rule content in Markdown
219
+ - `description`: Brief description
220
+
221
+ ### Via Files
222
+ Add Markdown files to the `data/rules/{project-type}/{category}/` directory:
223
+
224
+ ```markdown
225
+ # Rule Title
226
+
227
+ Description of the rule.
228
+
229
+ ## Guidelines
230
+
231
+ - Guideline 1
232
+ - Guideline 2
233
+
234
+ ## Examples
235
+
236
+ ```python
237
+ # Code example
238
+ ```
239
+ ```
240
+
241
+ ## Configuration Storage
242
+
243
+ User configurations are stored in `~/.stackguide/`:
244
+ - `configurations.json` - All saved configurations
245
+ - `rules/{project-type}/*.json` - User-created rules
246
+ - `web-docs/cache.json` - Cached web documentation
247
+
248
+ ## Development
249
+
250
+ ### Build
251
+
252
+ ```bash
253
+ npm run build
254
+ ```
255
+
256
+ ### Run in Development
257
+
258
+ ```bash
259
+ npm run dev
260
+ ```
261
+
262
+ ### Project Structure
263
+
264
+ ```
265
+ StackGuide-MCP/
266
+ ├── src/
267
+ │ ├── index.ts # Main entry point
268
+ │ ├── config/
269
+ │ │ ├── types.ts # TypeScript types
270
+ │ │ └── persistence.ts # Configuration storage
271
+ │ ├── resources/
272
+ │ │ ├── rulesProvider.ts # Rules management
273
+ │ │ └── knowledgeProvider.ts # Knowledge base
274
+ │ └── services/
275
+ │ ├── ruleManager.ts # Dynamic rule CRUD
276
+ │ └── webDocumentation.ts # Web docs fetcher
277
+ ├── data/
278
+ │ ├── rules/ # Rule files by project type
279
+ │ │ ├── python-django/
280
+ │ │ └── react-node/
281
+ │ └── knowledge/ # Knowledge files by project type
282
+ │ ├── python-django/
283
+ │ └── react-node/
284
+ ├── docs/
285
+ │ └── ADDING_CUSTOM_RULES.md # Guide for adding rules
286
+ ├── package.json
287
+ ├── tsconfig.json
288
+ └── README.md
289
+ ```
290
+
291
+ ## Dynamic Rule Management
292
+
293
+ ### Creating Rules from Templates
294
+
295
+ 1. **List available templates:**
296
+ ```
297
+ Use list_rule_templates
298
+ ```
299
+
300
+ 2. **Create a rule from template:**
301
+ ```
302
+ Use create_rule_from_template with:
303
+ - templateId: "coding-standard"
304
+ - projectType: "react-node"
305
+ - name: "My Team Standards"
306
+ ```
307
+
308
+ 3. **Edit the rule:**
309
+ ```
310
+ Use update_rule with the rule ID and new content
311
+ ```
312
+
313
+ ### Creating Rules from Scratch
314
+
315
+ ```
316
+ Use create_rule with:
317
+ - projectType: "python-django"
318
+ - name: "API Versioning"
319
+ - category: "best-practices"
320
+ - content: "# API Versioning\n\nAlways version your APIs..."
321
+ - description: "Guidelines for API versioning"
322
+ ```
323
+
324
+ ## Web Documentation
325
+
326
+ ### Fetching Documentation
327
+
328
+ ```
329
+ Use fetch_web_docs with:
330
+ - url: "https://react.dev/reference/react/useState"
331
+ - projectType: "react-node"
332
+ - title: "useState Hook"
333
+ ```
334
+
335
+ ### Getting Suggestions
336
+
337
+ ```
338
+ Use get_suggested_docs with projectType: "react-node"
339
+ ```
340
+
341
+ This returns popular documentation URLs for the framework.
342
+
343
+ ## Cursor Directory Integration
344
+
345
+ [cursor.directory](https://cursor.directory/rules/) is a community-driven repository of cursor rules for various technologies. StackGuide-MCP integrates with it to let you:
346
+
347
+ ### Browse Rules by Category
348
+
349
+ ```
350
+ Use browse_cursor_directory with category: "typescript"
351
+ ```
352
+
353
+ Available categories include: typescript, python, react, next.js, vue, django, fastapi, nestjs, prisma, tailwindcss, and many more.
354
+
355
+ ### Search for Rules
356
+
357
+ ```
358
+ Use search_cursor_directory with query: "react hooks best practices"
359
+ ```
360
+
361
+ ### Get Popular Rules
362
+
363
+ ```
364
+ Use get_popular_cursor_rules
365
+ ```
366
+
367
+ Returns featured rules from popular frameworks.
368
+
369
+ ### Import Rules
370
+
371
+ ```
372
+ Use import_cursor_directory_rule with:
373
+ - slug: "nextjs-react-typescript-cursor-rules"
374
+ - projectType: "react-typescript"
375
+ - category: "best-practices"
376
+ ```
377
+
378
+ This fetches the rule from cursor.directory and saves it to your local rules collection.
379
+
380
+ ## Publishing to npm
381
+
382
+ ### Prerequisites
383
+
384
+ 1. Create an npm account at [npmjs.com](https://www.npmjs.com/)
385
+ 2. Login to npm:
386
+ ```bash
387
+ npm login
388
+ ```
389
+
390
+ ### Steps to Publish
391
+
392
+ 1. **Update version** in `package.json`:
393
+ ```bash
394
+ npm version patch # or minor, major
395
+ ```
396
+
397
+ 2. **Build the project**:
398
+ ```bash
399
+ npm run build
400
+ ```
401
+
402
+ 3. **Test locally** (optional):
403
+ ```bash
404
+ npm link
405
+ stackguide-mcp # Test the command
406
+ npm unlink
407
+ ```
408
+
409
+ 4. **Publish to npm**:
410
+ ```bash
411
+ npm publish --access public
412
+ ```
413
+
414
+ Note: The package is scoped (`@stackguide/mcp-server`), so you need `--access public` for the first publish.
415
+
416
+ 5. **Verify publication**:
417
+ ```bash
418
+ npm view @stackguide/mcp-server
419
+ ```
420
+
421
+ ### Updating the Published Package
422
+
423
+ ```bash
424
+ npm version patch # Bump version
425
+ npm run build
426
+ npm publish
427
+ ```
428
+
429
+ ### Publishing Checklist
430
+
431
+ - [ ] All tests pass
432
+ - [ ] README is up to date
433
+ - [ ] Version is bumped
434
+ - [ ] Build succeeds
435
+ - [ ] `main` and `bin` fields in package.json point to correct files
436
+ - [ ] Keywords and description are accurate
437
+
438
+ ## Contributing
439
+
440
+ 1. Fork the repository
441
+ 2. Create a feature branch
442
+ 3. Add your rules/knowledge files or enhance the server
443
+ 4. Submit a pull request
444
+
445
+ ### Adding Support for New Frameworks
446
+
447
+ 1. Add project type to `src/config/types.ts`
448
+ 2. Create rule files in `data/rules/{new-type}/`
449
+ 3. Create knowledge files in `data/knowledge/{new-type}/`
450
+
451
+ ## License
452
+
453
+ GPL-3.0 - See [LICENSE](LICENSE) for details.
@@ -0,0 +1,201 @@
1
+ # Django Project Architecture
2
+
3
+ Recommended architecture patterns for scalable Django applications.
4
+
5
+ ## Layered Architecture
6
+
7
+ ```
8
+ ┌─────────────────────────────────────┐
9
+ │ Presentation │
10
+ │ (Views, Templates, Serializers) │
11
+ ├─────────────────────────────────────┤
12
+ │ Application │
13
+ │ (Services, Use Cases) │
14
+ ├─────────────────────────────────────┤
15
+ │ Domain │
16
+ │ (Models, Business Logic) │
17
+ ├─────────────────────────────────────┤
18
+ │ Infrastructure │
19
+ │ (Database, External APIs, Cache) │
20
+ └─────────────────────────────────────┘
21
+ ```
22
+
23
+ ## Service Layer Pattern
24
+
25
+ Separate business logic from views:
26
+
27
+ ```python
28
+ # services/article_service.py
29
+ from django.db import transaction
30
+ from typing import Optional
31
+
32
+ class ArticleService:
33
+ def __init__(self):
34
+ self.notification_service = NotificationService()
35
+
36
+ @transaction.atomic
37
+ def create_article(
38
+ self,
39
+ author_id: int,
40
+ title: str,
41
+ content: str,
42
+ tags: list[str] = None
43
+ ) -> Article:
44
+ """Create article with full business logic."""
45
+ author = User.objects.get(id=author_id)
46
+
47
+ article = Article.objects.create(
48
+ author=author,
49
+ title=title,
50
+ content=content,
51
+ slug=slugify(title)
52
+ )
53
+
54
+ if tags:
55
+ article.tags.set(Tag.objects.filter(name__in=tags))
56
+
57
+ # Side effects
58
+ self.notification_service.notify_followers(author, article)
59
+
60
+ return article
61
+
62
+ def publish_article(self, article_id: int) -> Article:
63
+ """Publish an article with validation."""
64
+ article = Article.objects.get(id=article_id)
65
+
66
+ if article.status == "published":
67
+ raise ValueError("Article already published")
68
+
69
+ if not article.content:
70
+ raise ValueError("Cannot publish empty article")
71
+
72
+ article.status = "published"
73
+ article.published_at = timezone.now()
74
+ article.save()
75
+
76
+ return article
77
+ ```
78
+
79
+ ## Repository Pattern
80
+
81
+ Abstract database operations:
82
+
83
+ ```python
84
+ # repositories/article_repository.py
85
+ from abc import ABC, abstractmethod
86
+ from typing import List, Optional
87
+
88
+ class ArticleRepositoryInterface(ABC):
89
+ @abstractmethod
90
+ def get_by_id(self, id: int) -> Optional[Article]:
91
+ pass
92
+
93
+ @abstractmethod
94
+ def get_published(self) -> List[Article]:
95
+ pass
96
+
97
+ @abstractmethod
98
+ def save(self, article: Article) -> Article:
99
+ pass
100
+
101
+ class DjangoArticleRepository(ArticleRepositoryInterface):
102
+ def get_by_id(self, id: int) -> Optional[Article]:
103
+ try:
104
+ return Article.objects.select_related("author").get(id=id)
105
+ except Article.DoesNotExist:
106
+ return None
107
+
108
+ def get_published(self) -> List[Article]:
109
+ return list(
110
+ Article.objects
111
+ .filter(status="published")
112
+ .select_related("author")
113
+ .prefetch_related("tags")
114
+ .order_by("-published_at")
115
+ )
116
+
117
+ def save(self, article: Article) -> Article:
118
+ article.save()
119
+ return article
120
+ ```
121
+
122
+ ## Domain Events
123
+
124
+ Decouple components with events:
125
+
126
+ ```python
127
+ # events/article_events.py
128
+ from dataclasses import dataclass
129
+ from datetime import datetime
130
+
131
+ @dataclass
132
+ class ArticlePublishedEvent:
133
+ article_id: int
134
+ author_id: int
135
+ published_at: datetime
136
+
137
+ # events/handlers.py
138
+ from django.dispatch import receiver
139
+ from .signals import article_published
140
+
141
+ @receiver(article_published)
142
+ def send_notifications(sender, event: ArticlePublishedEvent, **kwargs):
143
+ NotificationService().notify_subscribers(event)
144
+
145
+ @receiver(article_published)
146
+ def update_search_index(sender, event: ArticlePublishedEvent, **kwargs):
147
+ SearchService().index_article(event.article_id)
148
+ ```
149
+
150
+ ## Module Structure for Large Apps
151
+
152
+ ```
153
+ apps/
154
+ ├── articles/
155
+ │ ├── __init__.py
156
+ │ ├── admin.py
157
+ │ ├── apps.py
158
+ │ ├── models/
159
+ │ │ ├── __init__.py
160
+ │ │ ├── article.py
161
+ │ │ └── tag.py
162
+ │ ├── services/
163
+ │ │ ├── __init__.py
164
+ │ │ └── article_service.py
165
+ │ ├── repositories/
166
+ │ │ ├── __init__.py
167
+ │ │ └── article_repository.py
168
+ │ ├── api/
169
+ │ │ ├── __init__.py
170
+ │ │ ├── views.py
171
+ │ │ ├── serializers.py
172
+ │ │ └── urls.py
173
+ │ ├── tests/
174
+ │ │ ├── __init__.py
175
+ │ │ ├── test_models.py
176
+ │ │ ├── test_services.py
177
+ │ │ └── test_api.py
178
+ │ └── migrations/
179
+ ```
180
+
181
+ ## Dependency Injection
182
+
183
+ ```python
184
+ # container.py
185
+ class Container:
186
+ _instances = {}
187
+
188
+ @classmethod
189
+ def get_article_service(cls) -> ArticleService:
190
+ if "article_service" not in cls._instances:
191
+ repo = DjangoArticleRepository()
192
+ notification = NotificationService()
193
+ cls._instances["article_service"] = ArticleService(repo, notification)
194
+ return cls._instances["article_service"]
195
+
196
+ # views.py
197
+ class ArticleViewSet(viewsets.ViewSet):
198
+ def __init__(self, **kwargs):
199
+ super().__init__(**kwargs)
200
+ self.service = Container.get_article_service()
201
+ ```