healthy-companion 1.0.3

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.
@@ -0,0 +1,19 @@
1
+ name: Publish on NPM registry
2
+
3
+ on:
4
+ push:
5
+ branches: ['main']
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v2
12
+ - uses: actions/setup-node@v2
13
+ with:
14
+ node-version: 24.x
15
+ registry-url: https://registry.npmjs.org/
16
+ # - run: npm install
17
+ - run: npm publish --access public
18
+ env:
19
+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
package/AGENTS.md ADDED
@@ -0,0 +1,34 @@
1
+ # Core Rules
2
+
3
+ The following principles and rules **MUST** always be followed, under all circumstances:
4
+
5
+ ## I. Lightweight Architecture
6
+
7
+ Code, logic, and architecture **MUST** remain lightweight. Dependencies **MUST** be minimal and purposeful.
8
+
9
+ ## II. Simple and Minimalist Implementation
10
+
11
+ Code **MUST** be simple, clear, and readable—prefer straightforward, maintainable solutions over complex ones.
12
+ Keep the codebase minimal: avoid clever or tricky one-liners in favor of clarity.
13
+ Keep the code clean: avoid duplication.
14
+
15
+ ## III. Developer-Centric Documentation
16
+
17
+ All documentation **MUST** be developer-focused, with clear, concise technical explanations. Quickstart guides **MUST** enable local setup in under 5 minutes.
18
+ Keep the documentation minimal, and avoid duplication.
19
+
20
+ ## IV. Change Management
21
+
22
+ When changes are made, update the version in `package.json` and revise documentation (Markdown files) to reflect them.
23
+
24
+ ## V. Comprehensive Change Analysis
25
+
26
+ When implementing or fixing code, always verify correctness by analyzing related files and dependencies. But never write or run tests.
27
+
28
+ ## VI. Docs-Code Consistency
29
+
30
+ Documentation and code **MUST** stay in sync:
31
+
32
+ - Update docs whenever code changes and vice versa if docs are updated.
33
+ - Docs must match real behaviors.
34
+ - Any mismatch between docs and code should be addressed.
@@ -0,0 +1,62 @@
1
+ module.exports = [
2
+ {
3
+ languageOptions: {
4
+ parserOptions: {
5
+ ecmaVersion: 13,
6
+ impliedStrict: true,
7
+ }
8
+ },
9
+ rules: {
10
+ "no-trailing-spaces": "error",
11
+ "linebreak-style": ["error", "unix"],
12
+ "quotes": ["error", "double"],
13
+ "one-var": ["error", "never"],
14
+ "brace-style": ["error", "allman", { allowSingleLine: true }],
15
+ "space-before-blocks": "warn",
16
+ "func-call-spacing": "error",
17
+ "space-before-function-paren": "error",
18
+ "space-in-parens": ["error", "always", { exceptions: ["{}"] }],
19
+ "keyword-spacing": "error",
20
+ "comma-spacing": "error",
21
+ "space-unary-ops": "error",
22
+ "block-spacing": "error",
23
+ "arrow-spacing": "error",
24
+ "key-spacing": "error",
25
+ "comma-style": "error",
26
+ "space-infix-ops": "error",
27
+ "array-bracket-spacing": "error",
28
+ "object-curly-spacing": ["error", "always"],
29
+ "no-multi-spaces": "error",
30
+ "operator-linebreak": "error",
31
+ "function-paren-newline": "warn",
32
+ "arrow-body-style": ["error", "always"],
33
+ "no-template-curly-in-string": "error",
34
+ "no-new-object": "error",
35
+ "no-extra-parens": ["error", "all", { conditionalAssign: false }],
36
+ "no-empty-function": "error",
37
+ "no-empty": ["warn", { allowEmptyCatch: true }],
38
+ "no-eq-null": "error",
39
+ "no-extra-bind": "error",
40
+ "no-self-compare": "error",
41
+ "no-useless-call": "error",
42
+ "no-undefined": "error",
43
+ "no-array-constructor": "error",
44
+ "prefer-destructuring": ["error",
45
+ {
46
+ VariableDeclarator: { array: false, object: true }, AssignmentExpression: { array: false, object: false } }, { enforceForRenamedProperties: false
47
+ }
48
+ ],
49
+ "object-shorthand": "warn",
50
+ "prefer-spread": "warn",
51
+ "prefer-template": "warn",
52
+ "no-loop-func": "warn",
53
+ "prefer-rest-params": "warn",
54
+ "no-new-func": "warn",
55
+ "no-unneeded-ternary": "warn",
56
+ "no-process-exit": "off",
57
+ "require-await": "warn",
58
+ "indent": ["error", "tab", { MemberExpression: 0 }],
59
+ "no-tabs": 0,
60
+ },
61
+ },
62
+ ];
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "healthy-companion",
3
+ "version": "1.0.3",
4
+ "type": "module",
5
+ "description": "A healthy companion MCP server with todo and water tracking",
6
+ "main": "server.js",
7
+ "scripts": {
8
+ "start": "node server.js"
9
+ },
10
+ "dependencies": {
11
+ "@modelcontextprotocol/sdk": "^1.25.3",
12
+ "eslint": "^9.39.2",
13
+ "zod": "^4.3.6"
14
+ }
15
+ }
package/server.js ADDED
@@ -0,0 +1,27 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { registerTodoTools } from "./tools/todo.js";
4
+
5
+ const server = new McpServer({
6
+ name: "healthy-companion",
7
+ version: "1.0.0",
8
+ });
9
+
10
+ registerTodoTools( server );
11
+ const transport = new StdioServerTransport();
12
+
13
+ void async function main ()
14
+ {
15
+ try
16
+ {
17
+ const transport = new StdioServerTransport();
18
+ await server.connect( transport );
19
+ console.warn( "MCP server is running..." );
20
+ }
21
+ catch ( error )
22
+ {
23
+ console.error( "Server error:", error );
24
+ process.exit( 1 );
25
+
26
+ }
27
+ }()
package/tools/todo.js ADDED
@@ -0,0 +1,50 @@
1
+ import { z } from "zod";
2
+
3
+ const todos = [];
4
+
5
+ export function registerTodoTools ( server )
6
+ {
7
+ server.tool(
8
+ "todo_add",
9
+ "Add a TODO item",
10
+ { item: z.string().describe( "The text of the todo item" ) },
11
+ async ({ item }) =>
12
+ {
13
+ todos.push( item );
14
+ return {
15
+ content: [{ type: "text", text: `Added TODO: "${item}"` }],
16
+ };
17
+ }
18
+ );
19
+
20
+ server.tool(
21
+ "todo_list",
22
+ "List all TODO items",
23
+ {},
24
+ async () =>
25
+ {
26
+ if ( todos.length === 0 )
27
+ {
28
+ return { content: [{ type: "text", text: "No TODO items." }] };
29
+ }
30
+ const lines = todos.map( ( todo, idx ) => { return `${idx + 1}. ${todo}` }).join( "\n" );
31
+ return { content: [{ type: "text", text: lines }] };
32
+ }
33
+ );
34
+
35
+ server.tool(
36
+ "todo_remove",
37
+ "Remove a TODO item by its number",
38
+ { index: z.number().int().positive().describe( "1-based index of the item to remove" ) },
39
+ async ({ index }) =>
40
+ {
41
+ const i = index - 1;
42
+ if ( i < 0 || i >= todos.length )
43
+ {
44
+ return { content: [{ type: "text", text: `Invalid index: ${index}` }] };
45
+ }
46
+ const removed = todos.splice( i, 1 )[0];
47
+ return { content: [{ type: "text", text: `Removed TODO: "${removed}"` }] };
48
+ }
49
+ );
50
+ }