@mokoconsulting/mokoabs-mcp 0.0.0-stage → 4.0.2
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/.editorconfig +41 -0
- package/.gitattributes +94 -0
- package/.gitmessage +9 -0
- package/.mokogit/ISSUE_TEMPLATE/adr.md +110 -0
- package/.mokogit/ISSUE_TEMPLATE/bug_report.md +48 -0
- package/.mokogit/ISSUE_TEMPLATE/config.yml +18 -0
- package/.mokogit/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.mokogit/ISSUE_TEMPLATE/feature_request.md +51 -0
- package/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
- package/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md +69 -0
- package/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md +50 -0
- package/.mokogit/ISSUE_TEMPLATE/question.md +82 -0
- package/.mokogit/ISSUE_TEMPLATE/rfc.md +126 -0
- package/.mokogit/ISSUE_TEMPLATE/security.md +51 -0
- package/.mokogit/ISSUE_TEMPLATE/version.md +24 -0
- package/.mokogit/actions/resolve-source-dir/action.yml +72 -0
- package/.mokogit/workflows/apidocs.yml +132 -0
- package/.mokogit/workflows/auto-assign.yml +76 -0
- package/.mokogit/workflows/auto-dev-issue.yml +207 -0
- package/.mokogit/workflows/auto-release.yml +1787 -0
- package/.mokogit/workflows/branch-cleanup.yml +63 -0
- package/.mokogit/workflows/cascade.yml +645 -0
- package/.mokogit/workflows/ci-issue-reporter.yml +100 -0
- package/.mokogit/workflows/cleanup.yml +112 -0
- package/.mokogit/workflows/makefile-lint.yml +240 -0
- package/.mokogit/workflows/npm-build-test.yml +507 -0
- package/.mokogit/workflows/npm-sdk-check.yml +110 -0
- package/.mokogit/workflows/npm-tool-inventory.yml +81 -0
- package/.mokogit/workflows/pr-branch-check.yml +92 -0
- package/.mokogit/workflows/pre-release.yml +1134 -0
- package/.mokogit/workflows/rc-revert.yml +75 -0
- package/AGENTS.md +48 -0
- package/CHANGELOG.md +37 -0
- package/CODE_OF_CONDUCT.md +70 -0
- package/CONTRIBUTING.md +164 -0
- package/LICENSE +696 -0
- package/Makefile +94 -0
- package/README.md +109 -2
- package/SECURITY.md +245 -0
- package/build/README.md +7 -0
- package/dist/README.md +7 -0
- package/dist/index.js +153 -0
- package/package.json +34 -5
- package/sample/config.example.json +15 -0
- package/source/client.ts +132 -0
- package/source/config.ts +139 -0
- package/source/credentialStore.ts +216 -0
- package/source/index.ts +235 -0
- package/source/tokenReader.ts +120 -0
- package/source/types.ts +63 -0
- package/tsconfig.json +19 -0
package/Makefile
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# NPM / Node Project Makefile
|
|
2
|
+
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
#
|
|
5
|
+
# Native build/test/lint/package logic for an npm package (incl. MCP servers). The
|
|
6
|
+
# identity block below is the version source of truth — auto-filled per repo by the
|
|
7
|
+
# mokocli workflow sync (--makefiles).
|
|
8
|
+
|
|
9
|
+
# ==============================================================================
|
|
10
|
+
# Identity (auto-filled by workflow sync — the Makefile is the version source of truth)
|
|
11
|
+
# ==============================================================================
|
|
12
|
+
PROJECT_NAME := mcp-mokoabs
|
|
13
|
+
PROJECT_VERSION := 04.00.02
|
|
14
|
+
PLATFORM := npm
|
|
15
|
+
|
|
16
|
+
# ==============================================================================
|
|
17
|
+
# Configuration
|
|
18
|
+
# ==============================================================================
|
|
19
|
+
SRC_DIR := source
|
|
20
|
+
BUILD_DIR := build
|
|
21
|
+
NPM := npm
|
|
22
|
+
NODE := node
|
|
23
|
+
# Prefer `npm ci` when a lockfile is present (reproducible), else `npm install`.
|
|
24
|
+
NPM_INSTALL := $(shell [ -f package-lock.json ] && echo ci || echo install)
|
|
25
|
+
|
|
26
|
+
COLOR_RESET := \033[0m
|
|
27
|
+
COLOR_GREEN := \033[32m
|
|
28
|
+
COLOR_YELLOW := \033[33m
|
|
29
|
+
COLOR_BLUE := \033[34m
|
|
30
|
+
COLOR_RED := \033[31m
|
|
31
|
+
|
|
32
|
+
# ==============================================================================
|
|
33
|
+
# Targets
|
|
34
|
+
# ==============================================================================
|
|
35
|
+
.PHONY: help
|
|
36
|
+
help: ## Show this help message
|
|
37
|
+
@echo "$(COLOR_BLUE)$(PROJECT_NAME) v$(PROJECT_VERSION) — npm package$(COLOR_RESET)"
|
|
38
|
+
@echo ""
|
|
39
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " $(COLOR_BLUE)%-16s$(COLOR_RESET) %s\n", $$1, $$2}'
|
|
40
|
+
|
|
41
|
+
.PHONY: install-deps
|
|
42
|
+
install-deps: ## Install dependencies (npm ci if lockfile present, else install)
|
|
43
|
+
@$(NPM) $(NPM_INSTALL)
|
|
44
|
+
@echo "$(COLOR_GREEN)✓ dependencies installed$(COLOR_RESET)"
|
|
45
|
+
|
|
46
|
+
.PHONY: lint
|
|
47
|
+
lint: ## Run the package lint script when defined
|
|
48
|
+
@if grep -q '"lint"' package.json 2>/dev/null; then $(NPM) run lint; \
|
|
49
|
+
else echo "$(COLOR_YELLOW)⚠ no lint script — skipping$(COLOR_RESET)"; fi
|
|
50
|
+
|
|
51
|
+
.PHONY: validate
|
|
52
|
+
validate: lint ## Alias: static validation (lint)
|
|
53
|
+
|
|
54
|
+
.PHONY: test
|
|
55
|
+
test: ## Run the package test script when defined
|
|
56
|
+
@if grep -q '"test"' package.json 2>/dev/null; then $(NPM) test; \
|
|
57
|
+
else echo "$(COLOR_YELLOW)⚠ no test script — skipping$(COLOR_RESET)"; fi
|
|
58
|
+
|
|
59
|
+
.PHONY: clean
|
|
60
|
+
clean: ## Remove build artifacts
|
|
61
|
+
@rm -rf $(BUILD_DIR)
|
|
62
|
+
@echo "$(COLOR_GREEN)✓ cleaned $(BUILD_DIR)/$(COLOR_RESET)"
|
|
63
|
+
|
|
64
|
+
.PHONY: build
|
|
65
|
+
build: ## Run the package build script when defined
|
|
66
|
+
@if grep -q '"build"' package.json 2>/dev/null; then $(NPM) run build; \
|
|
67
|
+
echo "$(COLOR_GREEN)✓ built$(COLOR_RESET)"; \
|
|
68
|
+
else echo "$(COLOR_YELLOW)⚠ no build script — nothing to build$(COLOR_RESET)"; fi
|
|
69
|
+
|
|
70
|
+
.PHONY: minify
|
|
71
|
+
minify: ## Minify assets under $(SRC_DIR) via the mokocli build agent when available
|
|
72
|
+
@MOKO=$(or $(wildcard ../mokocli),$(wildcard $(HOME)/mokocli),$(wildcard /opt/mokocli)); \
|
|
73
|
+
if [ -n "$$MOKO" ] && [ -f "$$MOKO/build/minify.js" ]; then $(NODE) "$$MOKO/build/minify.js" $(SRC_DIR); \
|
|
74
|
+
elif [ -f scripts/minify.js ]; then $(NODE) scripts/minify.js; \
|
|
75
|
+
else echo "$(COLOR_YELLOW)⚠ no minify script found$(COLOR_RESET)"; fi
|
|
76
|
+
|
|
77
|
+
.PHONY: package
|
|
78
|
+
package: build ## Create the npm tarball (npm pack) + .sha256
|
|
79
|
+
@echo "$(COLOR_BLUE)Packaging $(PROJECT_NAME)-$(PROJECT_VERSION)...$(COLOR_RESET)"
|
|
80
|
+
@mkdir -p $(BUILD_DIR)
|
|
81
|
+
@$(NPM) pack --pack-destination $(BUILD_DIR) >/dev/null
|
|
82
|
+
@tgz=$$(ls -t $(BUILD_DIR)/*.tgz | head -1); \
|
|
83
|
+
sha256sum "$$tgz" | awk '{print $$1}' > "$$tgz.sha256"; \
|
|
84
|
+
echo "$(COLOR_GREEN)✓ packaged: $$tgz$(COLOR_RESET)"
|
|
85
|
+
|
|
86
|
+
.PHONY: release
|
|
87
|
+
release: validate test package ## Validate, test, and package for release
|
|
88
|
+
@echo "$(COLOR_GREEN)✓ release artifacts ready for $(PROJECT_NAME) v$(PROJECT_VERSION)$(COLOR_RESET)"
|
|
89
|
+
|
|
90
|
+
.PHONY: version
|
|
91
|
+
version: ## Print the resolved version (Makefile is the source of truth)
|
|
92
|
+
@echo "$(PROJECT_NAME) $(PROJECT_VERSION) ($(PLATFORM))"
|
|
93
|
+
|
|
94
|
+
.DEFAULT_GOAL := help
|
package/README.md
CHANGED
|
@@ -1,3 +1,110 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Template-NPM
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
> **Reporting issues:** This repository's issue tracker is disabled. All bugs, feature requests, and questions for MokoConsulting templates and shared tooling are tracked centrally in **[mokocli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/issues)** — please open issues there, not in the individual template repos.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
   
|
|
7
|
+
|
|
8
|
+
Template repository for creating MokoCLI-compliant Model Context Protocol (MCP) API servers. Provides the scaffolding, configuration patterns, and architecture conventions used by all Moko Consulting MCP servers, enabling AI assistants like Claude to interact with REST APIs through a standardized tool interface.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **MCP server scaffolding** -- pre-configured TypeScript project structure with entry point, tool registration, and stdio transport ready to go
|
|
13
|
+
- **Multi-connection support** -- built-in `config.json` pattern for managing multiple named API connections with a default fallback; all tools accept an optional `connection` parameter
|
|
14
|
+
- **REST API bridge architecture** -- standardized pattern for bridging any REST API as MCP tools, with typed request/response handling
|
|
15
|
+
- **TypeScript-first** -- full TypeScript setup with `tsconfig.json`, strict mode, and ES module output
|
|
16
|
+
- **Build tooling** -- Makefile with `build`, `dev`, `clean`, and `lint` targets; npm scripts for compilation and development
|
|
17
|
+
- **MokoCLI compliant** -- follows all Moko Consulting governance conventions: file headers, commit messages, `.gitattributes`, `.gitmessage`, PR/issue templates
|
|
18
|
+
- **Example configuration** -- `config.example.json` demonstrates the connection configuration schema
|
|
19
|
+
- **Documentation templates** -- wiki pages for API reference, architecture overview, and installation pre-generated
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
1. Create a new repository from this template (or clone directly):
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://git.mokoconsulting.tech/MokoConsulting/Template-NPM.git my-mcp-server
|
|
26
|
+
cd my-mcp-server
|
|
27
|
+
```
|
|
28
|
+
2. Install dependencies:
|
|
29
|
+
```bash
|
|
30
|
+
npm install
|
|
31
|
+
```
|
|
32
|
+
3. Copy and configure the connection file:
|
|
33
|
+
```bash
|
|
34
|
+
cp config.example.json config.json
|
|
35
|
+
# Edit config.json with your API credentials
|
|
36
|
+
```
|
|
37
|
+
4. Build the project:
|
|
38
|
+
```bash
|
|
39
|
+
npm run build
|
|
40
|
+
```
|
|
41
|
+
5. Run the server:
|
|
42
|
+
```bash
|
|
43
|
+
node build/index.js
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
Register the built server with your MCP client (Claude Code / Claude Desktop):
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"<name>": { "command": "npx", "args": ["-y", "@mokoconsulting/<package>"] }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Every tool accepts an optional `connection` parameter to target a named connection from your config; omit it to use the default. See [`docs/API.md`](docs/API.md) for the full tool reference.
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
| Path | Purpose |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `source/` | TypeScript source files (server entry, tool definitions, API client) |
|
|
65
|
+
| `config.example.json` | Example multi-connection configuration schema |
|
|
66
|
+
| `config.json` | Local connection configuration (gitignored) |
|
|
67
|
+
| `package.json` | npm dependencies and scripts |
|
|
68
|
+
| `tsconfig.json` | TypeScript compiler configuration |
|
|
69
|
+
| `scripts/` | Build and development utility scripts |
|
|
70
|
+
| `docs/` | Developer documentation |
|
|
71
|
+
| `Makefile` | Build, dev, clean, and lint targets |
|
|
72
|
+
|
|
73
|
+
## Requirements
|
|
74
|
+
|
|
75
|
+
- Node.js 20.0.0 or later
|
|
76
|
+
- npm 9+
|
|
77
|
+
- TypeScript 5+ (installed via npm)
|
|
78
|
+
|
|
79
|
+
## Documentation
|
|
80
|
+
|
|
81
|
+
Full documentation is available on the [Wiki](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki), including:
|
|
82
|
+
|
|
83
|
+
- [API](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki/API) -- tool reference and connection parameter documentation
|
|
84
|
+
- [ARCHITECTURE](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki/ARCHITECTURE) -- MCP server design and REST API bridge pattern
|
|
85
|
+
- [INSTALLATION](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki/INSTALLATION) -- setup prerequisites and configuration guide
|
|
86
|
+
|
|
87
|
+
## Contributing
|
|
88
|
+
|
|
89
|
+
See the wiki for development guidelines and contribution instructions.
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
This project is licensed under the GNU General Public License v3.0 or later -- see the [LICENSE](LICENSE) file.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
*[Moko Consulting](https://mokoconsulting.tech) -- [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)*
|
|
98
|
+
|
|
99
|
+
## Template CI Notes
|
|
100
|
+
|
|
101
|
+
Build/CI/release/version workflows are guarded to skip template repos (Template-*) and only run in repos created from them.
|
|
102
|
+
|
|
103
|
+
<!-- CI: platform-specific CI (ci-go / ci-php / npm-build-test / ci-joomla); ci-generic retired. -->
|
|
104
|
+
|
|
105
|
+
## Release automation
|
|
106
|
+
|
|
107
|
+
On a stable release the pipeline prunes superseded-major `version/*` branches, keeping only the current major.
|
|
108
|
+
<!-- The main->dev cascade (cascade-dev.yml) pushes to protected `dev` using the MOKOGIT_TOKEN PAT so the pre-receive hook accepts the push. See #257. -->
|
|
109
|
+
<!-- CI: npm-build-test.yml no longer defines a `ci-summary` job; a `needs:`+`if: always()` job never dispatches on the Gitea runner and stranded every main PR under the org `*` rule. Removed (matches ci-go.yml). -->
|
|
110
|
+
<!-- Release flow: bump-on-dev — the base version + CHANGELOG are bumped/promoted on `dev` pre-promotion (promote-rc via release_bump_dev.php); main publishes `--bump none --no-commit` so it never diverges from dev. -->
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
3
|
+
|
|
4
|
+
This file is part of a Moko Consulting project.
|
|
5
|
+
|
|
6
|
+
SPDX-License-Identifier: GPL-3.0-or-later
|
|
7
|
+
|
|
8
|
+
This program is free software; you can redistribute it and/or modify
|
|
9
|
+
it under the terms of the GNU General Public License as published by
|
|
10
|
+
the Free Software Foundation; either version 3 of the License, or
|
|
11
|
+
(at your option) any later version.
|
|
12
|
+
|
|
13
|
+
This program is distributed in the hope that it will be useful,
|
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
You should have received a copy of the GNU General Public License
|
|
19
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
# FILE INFORMATION
|
|
22
|
+
DEFGROUP: Template-Generic
|
|
23
|
+
INGROUP: Template-Generic.Documentation
|
|
24
|
+
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
|
25
|
+
PATH: /SECURITY.md
|
|
26
|
+
VERSION: 01.01.00
|
|
27
|
+
BRIEF: Security vulnerability reporting and handling policy
|
|
28
|
+
-->
|
|
29
|
+
|
|
30
|
+
# Security Policy
|
|
31
|
+
|
|
32
|
+
## Purpose and Scope
|
|
33
|
+
|
|
34
|
+
This document defines the security vulnerability reporting, response, and disclosure policy for Template-Generic and all repositories governed by these standards. It establishes the authoritative process for responsible disclosure, assessment, remediation, and communication of security issues.
|
|
35
|
+
|
|
36
|
+
## Supported Versions
|
|
37
|
+
|
|
38
|
+
Security updates are provided for the following versions:
|
|
39
|
+
|
|
40
|
+
| Version | Supported |
|
|
41
|
+
| ------- | ------------------ |
|
|
42
|
+
| [X.x.x] | :white_check_mark: |
|
|
43
|
+
| < [X.0] | :x: |
|
|
44
|
+
|
|
45
|
+
Only the current major version receives security updates. Users should upgrade to the latest supported version to receive security patches.
|
|
46
|
+
|
|
47
|
+
## Reporting a Vulnerability
|
|
48
|
+
|
|
49
|
+
Report security vulnerabilities via MokoGIT issue (preferred):
|
|
50
|
+
https://git.mokoconsulting.tech/MokoConsulting/Template-Generic/issues/new?template=security.yaml
|
|
51
|
+
|
|
52
|
+
Or email: hello@mokoconsulting.tech
|
|
53
|
+
|
|
54
|
+
### Where to Report
|
|
55
|
+
|
|
56
|
+
**DO NOT** create public GitHub issues for security vulnerabilities.
|
|
57
|
+
|
|
58
|
+
Report security vulnerabilities privately to:
|
|
59
|
+
|
|
60
|
+
**Email**: `security@[DOMAIN]`
|
|
61
|
+
|
|
62
|
+
**Subject Line**: `[SECURITY] Brief Description`
|
|
63
|
+
|
|
64
|
+
### What to Include
|
|
65
|
+
|
|
66
|
+
A complete vulnerability report should include:
|
|
67
|
+
|
|
68
|
+
1. **Description**: Clear explanation of the vulnerability
|
|
69
|
+
2. **Impact**: Potential security impact and severity assessment
|
|
70
|
+
3. **Affected Versions**: Which versions are vulnerable
|
|
71
|
+
4. **Reproduction Steps**: Detailed steps to reproduce the issue
|
|
72
|
+
5. **Proof of Concept**: Code, configuration, or demonstration (if applicable)
|
|
73
|
+
6. **Suggested Fix**: Proposed remediation (if known)
|
|
74
|
+
7. **Disclosure Timeline**: Your expectations for public disclosure
|
|
75
|
+
|
|
76
|
+
### Response Timeline
|
|
77
|
+
|
|
78
|
+
* **Initial Response**: Within 3 business days
|
|
79
|
+
* **Assessment Complete**: Within 7 business days
|
|
80
|
+
* **Fix Timeline**: Depends on severity (see below)
|
|
81
|
+
* **Disclosure**: Coordinated with reporter
|
|
82
|
+
|
|
83
|
+
## Severity Classification
|
|
84
|
+
|
|
85
|
+
Vulnerabilities are classified using the following severity levels:
|
|
86
|
+
|
|
87
|
+
### Critical
|
|
88
|
+
* Remote code execution
|
|
89
|
+
* Authentication bypass
|
|
90
|
+
* Data breach or exposure of sensitive information
|
|
91
|
+
* **Fix Timeline**: 7 days
|
|
92
|
+
|
|
93
|
+
### High
|
|
94
|
+
* Privilege escalation
|
|
95
|
+
* SQL injection or command injection
|
|
96
|
+
* Cross-site scripting (XSS) with significant impact
|
|
97
|
+
* **Fix Timeline**: 14 days
|
|
98
|
+
|
|
99
|
+
### Medium
|
|
100
|
+
* Information disclosure (limited scope)
|
|
101
|
+
* Denial of service
|
|
102
|
+
* Security misconfigurations with moderate impact
|
|
103
|
+
* **Fix Timeline**: 30 days
|
|
104
|
+
|
|
105
|
+
### Low
|
|
106
|
+
* Security best practice violations
|
|
107
|
+
* Minor information leaks
|
|
108
|
+
* Issues requiring user interaction or complex preconditions
|
|
109
|
+
* **Fix Timeline**: 60 days or next release
|
|
110
|
+
|
|
111
|
+
## Remediation Process
|
|
112
|
+
|
|
113
|
+
1. **Acknowledgment**: Security team confirms receipt and begins investigation
|
|
114
|
+
2. **Assessment**: Vulnerability is validated, severity assigned, and impact analyzed
|
|
115
|
+
3. **Development**: Security patch is developed and tested
|
|
116
|
+
4. **Review**: Patch undergoes security review and validation
|
|
117
|
+
5. **Release**: Fixed version is released with security advisory
|
|
118
|
+
6. **Disclosure**: Public disclosure follows coordinated timeline
|
|
119
|
+
|
|
120
|
+
## Security Advisories
|
|
121
|
+
|
|
122
|
+
Security advisories are published via:
|
|
123
|
+
|
|
124
|
+
* GitHub Security Advisories
|
|
125
|
+
* Release notes and CHANGELOG.md
|
|
126
|
+
* Security mailing list (when established)
|
|
127
|
+
|
|
128
|
+
Advisories include:
|
|
129
|
+
|
|
130
|
+
* CVE identifier (if applicable)
|
|
131
|
+
* Severity rating
|
|
132
|
+
* Affected versions
|
|
133
|
+
* Fixed versions
|
|
134
|
+
* Mitigation steps
|
|
135
|
+
* Attribution (with reporter consent)
|
|
136
|
+
|
|
137
|
+
## Security Best Practices
|
|
138
|
+
|
|
139
|
+
For repositories adopting MokoCLI:
|
|
140
|
+
|
|
141
|
+
### Required Controls
|
|
142
|
+
|
|
143
|
+
* Enable GitHub security features (Dependabot, code scanning)
|
|
144
|
+
* Implement branch protection on `main`
|
|
145
|
+
* Require code review for all changes
|
|
146
|
+
* Enforce signed commits (recommended)
|
|
147
|
+
* Use secrets management (never commit credentials)
|
|
148
|
+
* Maintain security documentation
|
|
149
|
+
* Follow secure coding standards defined in `/docs/policy/`
|
|
150
|
+
|
|
151
|
+
### CI/CD Security
|
|
152
|
+
|
|
153
|
+
* Validate all inputs
|
|
154
|
+
* Sanitize outputs
|
|
155
|
+
* Use least privilege access
|
|
156
|
+
* Pin dependencies with hash verification
|
|
157
|
+
* Scan for vulnerabilities in dependencies
|
|
158
|
+
* Audit third-party actions and tools
|
|
159
|
+
|
|
160
|
+
#### Automated Security Scanning
|
|
161
|
+
|
|
162
|
+
All repositories MUST implement:
|
|
163
|
+
|
|
164
|
+
**CodeQL Analysis**:
|
|
165
|
+
* Enabled for all supported languages (Python, JavaScript, TypeScript, Java, C/C++, C#, Go, Ruby)
|
|
166
|
+
* Runs on: push to main, pull requests, weekly schedule
|
|
167
|
+
* Query sets: `security-extended` and `security-and-quality`
|
|
168
|
+
* Configuration: `.github/workflows/codeql-analysis.yml`
|
|
169
|
+
|
|
170
|
+
**Dependabot Security Updates**:
|
|
171
|
+
* Weekly scans for vulnerable dependencies
|
|
172
|
+
* Automated pull requests for security patches
|
|
173
|
+
* Configuration: `.github/dependabot.yml`
|
|
174
|
+
|
|
175
|
+
**Secret Scanning**:
|
|
176
|
+
* Enabled by default with push protection
|
|
177
|
+
* Prevents accidental credential commits
|
|
178
|
+
* Partner patterns enabled
|
|
179
|
+
|
|
180
|
+
**Dependency Review**:
|
|
181
|
+
* Required for all pull requests
|
|
182
|
+
* Blocks introduction of known vulnerable dependencies
|
|
183
|
+
* Automatic license compliance checking
|
|
184
|
+
|
|
185
|
+
See [Security Scanning Policy](docs/policy/security-scanning.md) for detailed requirements.
|
|
186
|
+
|
|
187
|
+
### Dependency Management
|
|
188
|
+
|
|
189
|
+
* Keep dependencies up to date
|
|
190
|
+
* Monitor security advisories for dependencies
|
|
191
|
+
* Remove unused dependencies
|
|
192
|
+
* Audit new dependencies before adoption
|
|
193
|
+
* Document security-critical dependencies
|
|
194
|
+
|
|
195
|
+
## Compliance and Governance
|
|
196
|
+
|
|
197
|
+
This security policy is binding for all repositories governed by MokoCLI. Deviations require documented justification and approval from the Security Owner.
|
|
198
|
+
|
|
199
|
+
Security policies are reviewed and updated at least annually or following significant security incidents.
|
|
200
|
+
|
|
201
|
+
## Attribution and Recognition
|
|
202
|
+
|
|
203
|
+
We acknowledge and appreciate responsible disclosure. With your permission, we will:
|
|
204
|
+
|
|
205
|
+
* Credit you in security advisories
|
|
206
|
+
* List you in CHANGELOG.md for the fix release
|
|
207
|
+
* Recognize your contribution publicly (if desired)
|
|
208
|
+
|
|
209
|
+
## Contact and Escalation
|
|
210
|
+
|
|
211
|
+
* **Security Team**: security@[DOMAIN]
|
|
212
|
+
* **Primary Contact**: [CONTACT_EMAIL]
|
|
213
|
+
* **Escalation**: For urgent matters requiring immediate attention, contact the maintainer directly via GitHub
|
|
214
|
+
|
|
215
|
+
## Out of Scope
|
|
216
|
+
|
|
217
|
+
The following are explicitly out of scope:
|
|
218
|
+
|
|
219
|
+
* Issues in third-party dependencies (report directly to maintainers)
|
|
220
|
+
* Social engineering attacks
|
|
221
|
+
* Physical security issues
|
|
222
|
+
* Denial of service via resource exhaustion without amplification
|
|
223
|
+
* Issues requiring physical access to systems
|
|
224
|
+
* Theoretical vulnerabilities without proof of exploitability
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Metadata
|
|
229
|
+
|
|
230
|
+
| Field | Value |
|
|
231
|
+
| ------------ | ----------------------------------------------- |
|
|
232
|
+
| Document | Security Policy |
|
|
233
|
+
| Path | /SECURITY.md |
|
|
234
|
+
| Repository | https://git.mokoconsulting.tech/MokoConsulting/Template-Generic |
|
|
235
|
+
| Owner | [OWNER_NAME] |
|
|
236
|
+
| Scope | Security vulnerability handling |
|
|
237
|
+
| Applies To | All repositories governed by MokoCLI |
|
|
238
|
+
| Status | Active |
|
|
239
|
+
| Effective | [YYYY-MM-DD] |
|
|
240
|
+
|
|
241
|
+
## Revision History
|
|
242
|
+
|
|
243
|
+
| Date | Change Description | Author |
|
|
244
|
+
| ---------- | ------------------------------------------------- | --------------- |
|
|
245
|
+
| [YYYY-MM-DD] | Initial creation | [AUTHOR_NAME] |
|
package/build/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# build/
|
|
2
|
+
|
|
3
|
+
Generated build output lives here. Packaging is handled by the **mokocli-centric
|
|
4
|
+
build system** — mokocli clones and runs the shared build tooling in CI, and this
|
|
5
|
+
folder holds the generated artifacts (e.g. `build/packages/`) locally.
|
|
6
|
+
|
|
7
|
+
Only this `README.md` is tracked; everything else under `build/` is git-ignored.
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# dist/
|
|
2
|
+
|
|
3
|
+
Distributable artifacts live here — the packaged installer(s) and release
|
|
4
|
+
bundles emitted by the **mokocli-centric build system** (mokocli clones and runs
|
|
5
|
+
the shared build tooling in CI). Generated output, not source.
|
|
6
|
+
|
|
7
|
+
Only this `README.md` is tracked; everything else under `dist/` is git-ignored.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
3
|
+
*
|
|
4
|
+
* This file is part of a Moko Consulting project.
|
|
5
|
+
*
|
|
6
|
+
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
7
|
+
*
|
|
8
|
+
* FILE INFORMATION
|
|
9
|
+
* DEFGROUP: mokoabs-mcp.Server
|
|
10
|
+
* INGROUP: mokoabs-mcp
|
|
11
|
+
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoabs-mcp
|
|
12
|
+
* PATH: /source/index.ts
|
|
13
|
+
* VERSION: 01.00.00
|
|
14
|
+
* BRIEF: MCP server entry point — registers all Audiobookshelf API tools
|
|
15
|
+
*/
|
|
16
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
17
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
import { loadConfig, getConnection } from './config.js';
|
|
20
|
+
import { ApiClient } from './client.js';
|
|
21
|
+
let config;
|
|
22
|
+
function clientFor(connection) {
|
|
23
|
+
return new ApiClient(getConnection(config, connection));
|
|
24
|
+
}
|
|
25
|
+
function formatResponse(res) {
|
|
26
|
+
if (res.status >= 400) {
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: 'text', text: `Error: HTTP ${res.status}: ${JSON.stringify(res.data, null, 2)}` }],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
content: [{ type: 'text', text: JSON.stringify(res.data, null, 2) }],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// ── Shared parameter definitions ────────────────────────────────────────
|
|
36
|
+
const ConnectionParam = {
|
|
37
|
+
connection: z.string().optional().describe('Named connection from config (uses default if omitted)'),
|
|
38
|
+
};
|
|
39
|
+
const PaginationParams = {
|
|
40
|
+
limit: z.number().optional().describe('Max results'),
|
|
41
|
+
page: z.number().optional().describe('Page number (0-based)'),
|
|
42
|
+
};
|
|
43
|
+
function paginationQuery(params) {
|
|
44
|
+
const q = {};
|
|
45
|
+
if (params.limit !== undefined)
|
|
46
|
+
q['limit'] = String(params.limit);
|
|
47
|
+
if (params.page !== undefined)
|
|
48
|
+
q['page'] = String(params.page);
|
|
49
|
+
return q;
|
|
50
|
+
}
|
|
51
|
+
// ── Server ──────────────────────────────────────────────────────────────
|
|
52
|
+
const server = new McpServer({
|
|
53
|
+
name: 'mokoabs-mcp',
|
|
54
|
+
version: '1.0.0',
|
|
55
|
+
});
|
|
56
|
+
// ════════════════════════════════════════════════════════════════════════
|
|
57
|
+
// Audiobookshelf tools. The client prepends the "/api" prefix and a Bearer
|
|
58
|
+
// Authorization header, so endpoints below are written without "/api".
|
|
59
|
+
// ════════════════════════════════════════════════════════════════════════
|
|
60
|
+
// ── Libraries ────────────────────────────────────────────────────────────
|
|
61
|
+
server.tool('abs_libraries_list', 'List all Audiobookshelf libraries (id, name, mediaType).', { ...ConnectionParam }, async ({ connection }) => formatResponse(await clientFor(connection).get('/libraries')));
|
|
62
|
+
server.tool('abs_library_items', 'List items in a library (paginated). Optional ABS sort/desc/filter.', {
|
|
63
|
+
libraryId: z.string().describe('Library ID'),
|
|
64
|
+
sort: z.string().optional().describe('Sort field, e.g. "media.metadata.title"'),
|
|
65
|
+
desc: z.boolean().optional().describe('Sort descending'),
|
|
66
|
+
filter: z.string().optional().describe('ABS filter string, e.g. "genres.<base64>"'),
|
|
67
|
+
...PaginationParams,
|
|
68
|
+
...ConnectionParam,
|
|
69
|
+
}, async ({ libraryId, sort, desc, filter, limit, page, connection }) => {
|
|
70
|
+
const params = { ...paginationQuery({ limit, page }) };
|
|
71
|
+
if (sort)
|
|
72
|
+
params['sort'] = sort;
|
|
73
|
+
if (desc !== undefined)
|
|
74
|
+
params['desc'] = desc ? '1' : '0';
|
|
75
|
+
if (filter)
|
|
76
|
+
params['filter'] = filter;
|
|
77
|
+
return formatResponse(await clientFor(connection).get(`/libraries/${libraryId}/items`, params));
|
|
78
|
+
});
|
|
79
|
+
server.tool('abs_library_search', 'Search a library (books, series, authors, narrators, tags) by query.', {
|
|
80
|
+
libraryId: z.string().describe('Library ID'),
|
|
81
|
+
q: z.string().describe('Search query'),
|
|
82
|
+
limit: z.number().optional().describe('Max results per group'),
|
|
83
|
+
...ConnectionParam,
|
|
84
|
+
}, async ({ libraryId, q, limit, connection }) => {
|
|
85
|
+
const params = { q };
|
|
86
|
+
if (limit !== undefined)
|
|
87
|
+
params['limit'] = String(limit);
|
|
88
|
+
return formatResponse(await clientFor(connection).get(`/libraries/${libraryId}/search`, params));
|
|
89
|
+
});
|
|
90
|
+
server.tool('abs_library_scan', 'Trigger a scan of a library (picks up newly added/removed files).', {
|
|
91
|
+
libraryId: z.string().describe('Library ID'),
|
|
92
|
+
force: z.boolean().optional().describe('Force a full re-scan of all items'),
|
|
93
|
+
...ConnectionParam,
|
|
94
|
+
}, async ({ libraryId, force, connection }) => formatResponse(await clientFor(connection).post(`/libraries/${libraryId}/scan${force ? '?force=1' : ''}`)));
|
|
95
|
+
server.tool('abs_library_collections', 'List collections in a library.', { libraryId: z.string().describe('Library ID'), ...ConnectionParam }, async ({ libraryId, connection }) => formatResponse(await clientFor(connection).get(`/libraries/${libraryId}/collections`)));
|
|
96
|
+
server.tool('abs_library_series', 'List series in a library (paginated).', { libraryId: z.string().describe('Library ID'), ...PaginationParams, ...ConnectionParam }, async ({ libraryId, limit, page, connection }) => formatResponse(await clientFor(connection).get(`/libraries/${libraryId}/series`, paginationQuery({ limit, page }))));
|
|
97
|
+
server.tool('abs_library_authors', 'List authors in a library.', { libraryId: z.string().describe('Library ID'), ...ConnectionParam }, async ({ libraryId, connection }) => formatResponse(await clientFor(connection).get(`/libraries/${libraryId}/authors`)));
|
|
98
|
+
// ── Items ────────────────────────────────────────────────────────────────
|
|
99
|
+
server.tool('abs_item_get', 'Get a library item by ID (optionally with expanded media/metadata).', {
|
|
100
|
+
itemId: z.string().describe('Library item ID'),
|
|
101
|
+
expanded: z.boolean().optional().describe('Include full media/metadata'),
|
|
102
|
+
...ConnectionParam,
|
|
103
|
+
}, async ({ itemId, expanded, connection }) => {
|
|
104
|
+
const params = {};
|
|
105
|
+
if (expanded)
|
|
106
|
+
params['expanded'] = '1';
|
|
107
|
+
return formatResponse(await clientFor(connection).get(`/items/${itemId}`, params));
|
|
108
|
+
});
|
|
109
|
+
// ── Account ──────────────────────────────────────────────────────────────
|
|
110
|
+
server.tool('abs_me', 'Get the authenticated user (from the API key).', { ...ConnectionParam }, async ({ connection }) => formatResponse(await clientFor(connection).get('/me')));
|
|
111
|
+
// ── Generic API Call ────────────────────────────────────────────────────
|
|
112
|
+
server.tool('api_request', 'Make a raw Audiobookshelf API request to any endpoint (path is relative to /api).', {
|
|
113
|
+
method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).describe('HTTP method'),
|
|
114
|
+
endpoint: z.string().describe('API endpoint path relative to /api (e.g. "/libraries")'),
|
|
115
|
+
body: z.record(z.string(), z.unknown()).optional().describe('Request body for POST/PUT/PATCH'),
|
|
116
|
+
params: z.record(z.string(), z.string()).optional().describe('Query parameters'),
|
|
117
|
+
...ConnectionParam,
|
|
118
|
+
}, async ({ method, endpoint, body, params, connection }) => {
|
|
119
|
+
const client = clientFor(connection);
|
|
120
|
+
switch (method) {
|
|
121
|
+
case 'GET':
|
|
122
|
+
return formatResponse(await client.get(endpoint, params));
|
|
123
|
+
case 'POST':
|
|
124
|
+
return formatResponse(await client.post(endpoint, body));
|
|
125
|
+
case 'PUT':
|
|
126
|
+
return formatResponse(await client.put(endpoint, body));
|
|
127
|
+
case 'PATCH':
|
|
128
|
+
return formatResponse(await client.patch(endpoint, body));
|
|
129
|
+
case 'DELETE':
|
|
130
|
+
return formatResponse(await client.delete(endpoint));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
// ── Connections Management ──────────────────────────────────────────────
|
|
134
|
+
server.tool('list_connections', 'List configured Audiobookshelf connections.', {}, async () => {
|
|
135
|
+
const lines = Object.entries(config.connections).map(([name, conn]) => {
|
|
136
|
+
const is_default = name === config.defaultConnection ? ' (default)' : '';
|
|
137
|
+
return ` ${name}${is_default}: ${conn.baseUrl}`;
|
|
138
|
+
});
|
|
139
|
+
return {
|
|
140
|
+
content: [{ type: 'text', text: `Configured connections:\n${lines.join('\n')}` }],
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
// ── Start Server ────────────────────────────────────────────────────────
|
|
144
|
+
async function main() {
|
|
145
|
+
config = await loadConfig();
|
|
146
|
+
const transport = new StdioServerTransport();
|
|
147
|
+
await server.connect(transport);
|
|
148
|
+
}
|
|
149
|
+
main().catch((err) => {
|
|
150
|
+
process.stderr.write(`Fatal: ${err}\n`);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@mokoconsulting/mokoabs-mcp",
|
|
3
|
+
"version": "4.0.2",
|
|
4
|
+
"description": "MCP server for Audiobookshelf API operations",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mokoabs-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"lint": "eslint source/",
|
|
15
|
+
"setup": "node scripts/setup.mjs",
|
|
16
|
+
"clean": "rm -rf dist/"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@modelcontextprotocol/sdk": "1.12.1",
|
|
20
|
+
"zod": "^3.24.4"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.15.3",
|
|
24
|
+
"typescript": "^5.8.3"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=20.0.0"
|
|
28
|
+
},
|
|
29
|
+
"license": "GPL-3.0-or-later",
|
|
30
|
+
"author": "Moko Consulting <hello@mokoconsulting.tech>",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://git.mokoconsulting.tech/MokoConsulting/mokoabs-mcp.git"
|
|
34
|
+
}
|
|
35
|
+
}
|