Skip to content

Commit 842cab8

Browse files
committed
docs: add JSDoc comments to source files and fix license
- Add comprehensive JSDoc comments to all non-test TypeScript files - Fix license from MIT back to CC BY-NC-SA 4.0 - Update package.json license field - Add template repo badges to README - Add proper license badge and attribution to README
1 parent fd44875 commit 842cab8

File tree

9 files changed

+159
-27
lines changed

9 files changed

+159
-27
lines changed

LICENSE

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
1-
MIT License
1+
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
22

3-
Copyright (c) 2025
3+
Copyright (c) 2025 Joseph Mearman
44

5-
Permission is hereby granted, free of charge, to any person obtaining a copy
6-
of this software and associated documentation files (the "Software"), to deal
7-
in the Software without restriction, including without limitation the rights
8-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-
copies of the Software, and to permit persons to whom the Software is
10-
furnished to do so, subject to the following conditions:
5+
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
116

12-
The above copyright notice and this permission notice shall be included in all
13-
copies or substantial portions of the Software.
7+
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
148

15-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
9+
You are free to:
10+
- Share — copy and redistribute the material in any medium or format
11+
- Adapt — remix, transform, and build upon the material
12+
13+
Under the following terms:
14+
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
15+
- NonCommercial — You may not use the material for commercial purposes.
16+
- ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
17+
18+
No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
A template repository for building Model Context Protocol (MCP) servers with TypeScript.
44

5+
[![Use this template](https://img.shields.io/badge/Use%20this%20template-2ea44f?style=for-the-badge)](https://github.com/Mearman/mcp-template/generate)
6+
[![GitHub](https://img.shields.io/github/stars/Mearman/mcp-template?style=for-the-badge)](https://github.com/Mearman/mcp-template)
7+
58
## Features
69

710
- 🚀 Full TypeScript support with strict mode
@@ -214,7 +217,9 @@ This template includes semantic-release for automated versioning and publishing:
214217

215218
## License
216219

217-
MIT
220+
[![CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg)](http://creativecommons.org/licenses/by-nc-sa/4.0/)
221+
222+
This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).
218223

219224
## Contributing
220225

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"keywords": ["mcp", "model-context-protocol", "typescript", "template", "mcp-server"],
2020
"author": "",
21-
"license": "MIT",
21+
"license": "CC-BY-NC-SA-4.0",
2222
"repository": {
2323
"type": "git",
2424
"url": "git+https://github.com/Mearman/mcp-template.git"

src/index.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1+
/**
2+
* @fileoverview Basic tests for the MCP server entry point
3+
* @module index.test
4+
*/
5+
16
import { describe, expect, it } from 'vitest';
27

8+
/**
9+
* Test suite for the MCP server module
10+
*/
311
describe('MCP Server', () => {
12+
/**
13+
* Test that the server module can be imported as an ES module
14+
*/
415
it('should export as ES module', async () => {
5-
// This test verifies the module can be imported
616
const module = await import('./index.js');
717
expect(module).toBeDefined();
818
});

src/index.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
#!/usr/bin/env node
2+
/**
3+
* @fileoverview MCP server entry point that sets up and starts the server
4+
* @module index
5+
*/
6+
27
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
38
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
49
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
510
import { z } from 'zod';
611
import { zodToJsonSchema } from 'zod-to-json-schema';
712
import { ExampleToolSchema, exampleTool } from './tools/example.js';
813

14+
/**
15+
* Create the MCP server instance with configured capabilities
16+
*/
917
const server = new Server(
1018
{
1119
name: 'mcp-template',
@@ -18,7 +26,10 @@ const server = new Server(
1826
},
1927
);
2028

21-
// List available tools
29+
/**
30+
* Register handler for listing available tools
31+
* @returns List of available tools with their schemas
32+
*/
2233
server.setRequestHandler(ListToolsRequestSchema, async () => {
2334
return {
2435
tools: [
@@ -31,7 +42,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
3142
};
3243
});
3344

34-
// Handle tool calls
45+
/**
46+
* Register handler for executing tool calls
47+
* @param request - The tool call request containing tool name and arguments
48+
* @returns Tool execution result
49+
*/
3550
server.setRequestHandler(CallToolRequestSchema, async (request) => {
3651
const { name, arguments: args } = request.params;
3752

@@ -43,11 +58,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
4358
}
4459
});
4560

46-
// Start the server
61+
/**
62+
* Start the MCP server using stdio transport
63+
*/
4764
const transport = new StdioServerTransport();
4865
await server.connect(transport);
4966

50-
// Handle shutdown gracefully
67+
/**
68+
* Handle graceful shutdown on SIGINT (Ctrl+C)
69+
*/
5170
process.on('SIGINT', async () => {
5271
await server.close();
5372
process.exit(0);

src/tools/example.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
/**
2+
* @fileoverview Unit tests for the example tool
3+
* @module tools/example.test
4+
*/
5+
16
import { describe, expect, it } from 'vitest';
27
import { exampleTool } from './example.js';
38

9+
/**
10+
* Test suite for the example tool functionality
11+
*/
412
describe('exampleTool', () => {
13+
/**
14+
* Test that the tool correctly echoes back the input message
15+
*/
516
it('should echo the message', async () => {
617
const result = await exampleTool({ message: 'Hello, world!' });
718
expect(result.content[0]).toEqual({
@@ -10,6 +21,9 @@ describe('exampleTool', () => {
1021
});
1122
});
1223

24+
/**
25+
* Test that the uppercase option works correctly
26+
*/
1327
it('should convert to uppercase when requested', async () => {
1428
const result = await exampleTool({
1529
message: 'Hello, world!',
@@ -21,6 +35,9 @@ describe('exampleTool', () => {
2135
});
2236
});
2337

38+
/**
39+
* Test that invalid inputs are properly rejected with validation errors
40+
*/
2441
it('should validate input', async () => {
2542
await expect(exampleTool({})).rejects.toThrow();
2643
await expect(exampleTool({ message: 123 })).rejects.toThrow();

src/tools/example.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
/**
2+
* @fileoverview Example tool implementation demonstrating MCP tool structure
3+
* @module tools/example
4+
*/
5+
16
import { z } from 'zod';
27

8+
/**
9+
* Input schema for the example tool
10+
* @description Validates input parameters for the echo tool
11+
*/
312
export const ExampleToolSchema = z.object({
413
message: z.string().describe('The message to echo back'),
514
uppercase: z
@@ -9,8 +18,23 @@ export const ExampleToolSchema = z.object({
918
.describe('Whether to return the message in uppercase'),
1019
});
1120

21+
/**
22+
* TypeScript type for the example tool input
23+
*/
1224
export type ExampleToolInput = z.infer<typeof ExampleToolSchema>;
1325

26+
/**
27+
* Example tool that echoes back the input message
28+
* @param args - Raw input arguments to be validated against ExampleToolSchema
29+
* @returns MCP tool response with the echoed message
30+
* @throws {z.ZodError} If input validation fails
31+
*
32+
* @example
33+
* ```typescript
34+
* const result = await exampleTool({ message: "Hello", uppercase: true });
35+
* // Returns: { content: [{ type: 'text', text: 'Echo: HELLO' }] }
36+
* ```
37+
*/
1438
export async function exampleTool(args: unknown) {
1539
const input = ExampleToolSchema.parse(args);
1640

src/utils/validation.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
/**
2+
* @fileoverview Unit tests for validation utilities and schemas
3+
* @module utils/validation.test
4+
*/
5+
16
import { describe, expect, it } from 'vitest';
27
import { dateSchema, timestampSchema, urlSchema, validateInput } from './validation.js';
38

9+
/**
10+
* Test suite for validation schemas
11+
*/
412
describe('validation schemas', () => {
13+
/**
14+
* Tests for URL validation schema
15+
*/
516
describe('urlSchema', () => {
617
it('should accept valid URLs', () => {
718
expect(urlSchema.parse('https://example.com')).toBe('https://example.com');
@@ -14,6 +25,9 @@ describe('validation schemas', () => {
1425
});
1526
});
1627

28+
/**
29+
* Tests for date validation schema (YYYY-MM-DD format)
30+
*/
1731
describe('dateSchema', () => {
1832
it('should accept valid dates', () => {
1933
expect(dateSchema.parse('2024-01-01')).toBe('2024-01-01');
@@ -27,6 +41,9 @@ describe('validation schemas', () => {
2741
});
2842
});
2943

44+
/**
45+
* Tests for timestamp validation schema (YYYYMMDDHHmmss format)
46+
*/
3047
describe('timestampSchema', () => {
3148
it('should accept valid timestamps', () => {
3249
expect(timestampSchema.parse('20240101120000')).toBe('20240101120000');
@@ -39,6 +56,9 @@ describe('validation schemas', () => {
3956
});
4057
});
4158

59+
/**
60+
* Test suite for the validateInput utility function
61+
*/
4262
describe('validateInput', () => {
4363
it('should return parsed value for valid input', () => {
4464
const result = validateInput(urlSchema, 'https://example.com');

src/utils/validation.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,64 @@
1+
/**
2+
* @fileoverview Common validation schemas and utilities for input validation
3+
* @module utils/validation
4+
*/
5+
16
import { z } from 'zod';
27

38
/**
49
* Common validation schemas for reuse across tools
510
*/
611

7-
// URL validation
12+
/**
13+
* Schema for validating URL strings
14+
* @description Ensures the input is a valid URL format
15+
* @example
16+
* ```typescript
17+
* const validUrl = urlSchema.parse("https://example.com");
18+
* // Returns: "https://example.com"
19+
* ```
20+
*/
821
export const urlSchema = z.string().url('Invalid URL format');
922

10-
// Date validation
23+
/**
24+
* Schema for validating date strings in YYYY-MM-DD format
25+
* @description Validates that the input matches the YYYY-MM-DD date format
26+
* @example
27+
* ```typescript
28+
* const validDate = dateSchema.parse("2024-01-15");
29+
* // Returns: "2024-01-15"
30+
* ```
31+
*/
1132
export const dateSchema = z
1233
.string()
1334
.regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format');
1435

15-
// Timestamp validation (YYYYMMDDHHmmss)
36+
/**
37+
* Schema for validating timestamp strings in YYYYMMDDHHmmss format
38+
* @description Validates 14-digit timestamp strings commonly used by web archives
39+
* @example
40+
* ```typescript
41+
* const validTimestamp = timestampSchema.parse("20240115143022");
42+
* // Returns: "20240115143022" (2024-01-15 14:30:22)
43+
* ```
44+
*/
1645
export const timestampSchema = z
1746
.string()
1847
.regex(/^\d{14}$/, 'Timestamp must be in YYYYMMDDHHmmss format');
1948

2049
/**
2150
* Validate and parse input with helpful error messages
51+
* @param schema - Zod schema to validate against
52+
* @param input - Unknown input to validate
53+
* @returns Validated and typed input
54+
* @throws {Error} If validation fails, with formatted error messages
55+
*
56+
* @example
57+
* ```typescript
58+
* const schema = z.object({ name: z.string() });
59+
* const validated = validateInput(schema, { name: "test" });
60+
* // Returns: { name: "test" } with TypeScript type inference
61+
* ```
2262
*/
2363
export function validateInput<T>(schema: z.ZodSchema<T>, input: unknown): T {
2464
try {

0 commit comments

Comments
 (0)