Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
groups:
runtime-dependencies:
dependency-type: "production"
toolchain:
dependency-type: "development"
patterns:
- "@eslint/js"
- "@types/*"
- "@vitest/coverage-v8"
- "eslint"
- "eslint-config-prettier"
- "prettier"
- "tsx"
- "typescript"
- "typescript-eslint"
- "vitest"
ignore:
# Major bumps for coupled toolchain packages need manual coordination
- dependency-name: "typescript"
update-types: ["version-update:semver-major"]
- dependency-name: "typescript-eslint"
update-types: ["version-update:semver-major"]
- dependency-name: "eslint"
update-types: ["version-update:semver-major"]
- dependency-name: "@eslint/*"
update-types: ["version-update:semver-major"]
- dependency-name: "vitest"
update-types: ["version-update:semver-major"]
- dependency-name: "@vitest/*"
update-types: ["version-update:semver-major"]
commit-message:
prefix: "chore(deps)"
open-pull-requests-limit: 10
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Build
run: npm run build

- name: Test
run: npm test

- name: Test coverage
run: npm run test:coverage
continue-on-error: true
Comment on lines +24 to +34

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow runs npm run lint, npm test, and npm run test:coverage, but package.json currently doesn't define lint, test, or test:coverage scripts. This will cause CI to fail with "Missing script" errors unless those scripts (and their toolchain deps) are added.

Suggested change
run: npm run lint
- name: Build
run: npm run build
- name: Test
run: npm test
- name: Test coverage
run: npm run test:coverage
continue-on-error: true
run: npm run lint --if-present
- name: Build
run: npm run build
- name: Test
run: npm run test --if-present
- name: Test coverage
run: npm run test:coverage --if-present

Copilot uses AI. Check for mistakes.
39 changes: 39 additions & 0 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Dependabot auto-merge

on:
pull_request_target:
types:
- opened
- reopened
- synchronize
- ready_for_review

permissions:
contents: write
pull-requests: write

jobs:
auto-merge:
if: github.actor == 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: Fetch Dependabot metadata
id: meta
uses: dependabot/fetch-metadata@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Approve and enable auto-merge
if: |
steps.meta.outputs.update-type != 'version-update:semver-major' ||
steps.meta.outputs.package-ecosystem == 'github_actions'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
CURRENT_LOGIN="$(gh api user --jq .login)"
ALREADY_APPROVED="$(gh api "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews" --jq '[.[] | select(.user.login == "'"$CURRENT_LOGIN"'" and .state == "APPROVED")] | length')"
if [ "$ALREADY_APPROVED" -eq 0 ]; then
gh pr review --approve "$PR_URL"
fi
gh pr merge --auto --squash "$PR_URL"
35 changes: 35 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: PR Title

on:
pull_request_target:
types:
- opened
- edited
- reopened
- synchronize

permissions:
pull-requests: read

jobs:
conventional-pr-title:
if: ${{ github.event.pull_request.base.ref == 'main' }}
runs-on: ubuntu-latest
steps:
- name: Validate conventional PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
pattern='^(feat|fix|docs|chore|refactor|test|perf|build|ci|revert)(\([[:alnum:]_.-]+\))?!?: .+'

if [[ "$PR_TITLE" =~ $pattern ]]; then
echo "PR title is valid: $PR_TITLE"
exit 0
fi

echo "PR title must use Conventional Commits because squash merges become release-please input."
echo "Allowed prefixes: feat, fix, docs, chore, refactor, test, perf, build, ci, revert"
echo "Examples:"
echo " fix: harden push approval auth flow"
echo " feat(auth): add TOTP support"
exit 1
73 changes: 73 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Release Please - Automated versioning and npm publishing
#
# How it works:
# 1. Every push to main with conventional commits updates a "Release PR"
# 2. When you merge the Release PR, it:
# - Updates version in package.json
# - Updates CHANGELOG.md
# - Creates a GitHub Release with tag
# - Triggers the npm publish job below
#
# Commit message format:
# feat: add new feature → minor version bump
# fix: fix a bug → patch version bump
# feat!: breaking change → major version bump
# chore/docs: no version bump
#
# npm Publishing:
# Uses Trusted Publishing (OIDC) - no NPM_TOKEN needed!
# Requires Node 24+ for npm 11.5.1+ OIDC support.
# Configure at: https://www.npmjs.com/package/@verygoodplugins/mcp-{name}/access
#
# RELEASE_PLEASE_TOKEN:
# Uses org-level PAT so the Release PR triggers CI workflows.
# PRs created by GITHUB_TOKEN don't trigger other workflows (GitHub security).

name: Release Please

on:
push:
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
release-please:
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
manifest-file: ".release-please-manifest.json"
config-file: "release-please-config.json"
Comment on lines +47 to +48

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manifest-file and config-file referenced here do not exist in the repository (.release-please-manifest.json, release-please-config.json). release-please-action will fail at runtime unless these files are added or the workflow is switched to non-manifest configuration.

Suggested change
manifest-file: ".release-please-manifest.json"
config-file: "release-please-config.json"
release-type: "node"

Copilot uses AI. Check for mistakes.
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}

npm-publish:
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}
runs-on: ubuntu-latest
environment: npm
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"

# Use npm install for cross-version lockfile compatibility
- run: npm install
- run: npm run build
- run: npm test

# Trusted Publishing: No NPM_TOKEN needed!
- run: npm publish --provenance --access public
53 changes: 53 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Security

on:
schedule:
- cron: "0 0 * * 0" # Weekly on Sunday
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read
security-events: write

jobs:
codeql:
name: CodeQL Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: typescript

- name: Autobuild
uses: github/codeql-action/autobuild@v4

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4

audit:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- run: npm ci

- name: Audit dependencies
run: npm audit --audit-level=high
continue-on-error: true

- name: Check for known vulnerabilities
run: npx better-npm-audit audit --level high
continue-on-error: true
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100
}
26 changes: 26 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ESLint flat config for VGP MCP servers
// Requires: eslint ^9.0.0, typescript-eslint ^8.0.0
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
{
files: ['src/**/*.ts'],
rules: {
// MCP stdio servers must not write to stdout outside the protocol.
'no-console': ['error', { allow: ['error', 'warn'] }],
// Allow unused vars prefixed with underscore
Comment on lines +10 to +14

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-console is enforced for all src/**/*.ts with only error/warn allowed, but src/cli.ts uses console.log for normal CLI output. This will make lint fail once wired up. Consider scoping the stricter no-console rule to the stdio server entrypoint (e.g., src/server.ts) or adding an override/exception for src/cli.ts.

Copilot uses AI. Check for mistakes.
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
],
// Allow explicit any in some cases (MCP tools often need flexibility)
'@typescript-eslint/no-explicit-any': 'warn',
},
},
{
ignores: ['dist/', 'node_modules/', '**/*.js', '**/*.mjs', '**/*.cjs'],
}
);
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@
"author": "Claude",
"license": "GPL-3.0-or-later",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.4.1",
"@modelcontextprotocol/sdk": "^1.25.1",
"axios": "^1.6.7",
"dotenv": "^16.4.5",
"dotenv": "^17.2.3",
"fs-extra": "^11.2.0",
"marked": "^17.0.0",
"zod": "^3.23.8",
"zod": "^3.24.1",
"zod-to-json-schema": "^3.24.1"
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^22.10.0",
"@types/node": "^22.10.5",
"rimraf": "^5.0.5",
"tsx": "^4.7.1",
"typescript": "^5.3.3"
"tsx": "^4.19.2",
"typescript": "^5.7.3"
Comment on lines 40 to +45

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repo now includes ESLint/Vitest/Prettier configs and CI runs npm run lint/npm test/npm run test:coverage, but the required toolchain deps are not listed here (e.g., eslint, @eslint/js, typescript-eslint, vitest, @vitest/coverage-v8, etc.). As-is, installs/tests in CI will fail once those scripts are added (and vitest/config / @eslint/js imports will be unresolved). Add the missing devDependencies (and corresponding npm scripts) or remove the configs/workflow steps that rely on them.

Copilot uses AI. Check for mistakes.
},
"publishConfig": {
"access": "public"
Expand Down
13 changes: 13 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
globals: true,
environment: 'node',
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: ['node_modules/', 'dist/', 'tests/', '*.config.*'],

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage excludes dist/, but this repo’s build output directory is build/ (see .gitignore). Consider excluding build/ instead (or in addition) so generated JS doesn’t affect coverage results.

Suggested change
exclude: ['node_modules/', 'dist/', 'tests/', '*.config.*'],
exclude: ['node_modules/', 'dist/', 'build/', 'tests/', '*.config.*'],

Copilot uses AI. Check for mistakes.
},
},
});
Loading