Knol

Knol Docs

Tenant + OSS Documentation

OSS SDK: MCP Test Guide

Validation and test strategy for the MCP server.

Testing Guide

This document explains how to test the Knol MCP server locally.

Prerequisites

Unit Testing Setup

1. Install Testing Dependencies

npm install --save-dev jest @types/jest ts-jest

2. Create jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  roots: ['<rootDir>/tests'],
  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

3. Add Test Script to package.json

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  }
}

Manual Testing

Test 1: Server Starts Successfully

KNOL_API_KEY="test-key" npm start &
sleep 2
kill %1

Expected output: Server starts without errors.

Test 2: Environment Variable Validation

npm start

Expected output: Error about missing KNOL_API_KEY.

Test 3: Tools List Request

Create test-tools-list.json:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

Send the request:

cat test-tools-list.json | \
  KNOL_API_KEY="test-key" npm start

Expected: Response with tool definitions for all 7 tools.

Test 4: API Connection Test

Test if the server can reach the Knol API:

KNOL_API_KEY="sk_test_actual_key" \
KNOL_API_URL="http://localhost:8080" \
KNOL_USER_ID="test-user" \
npm start

Create test-search.json:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_search",
    "arguments": {
      "query": "test",
      "limit": 1
    }
  }
}

Send:

cat test-search.json | \
  KNOL_API_KEY="sk_test_actual_key" \
  KNOL_API_URL="http://localhost:8080" \
  npm start

Expected: Response from Knol API (success or API error).

Integration Testing

Test 1: Full Memory Lifecycle

KNOL_API_KEY="your-key" \
KNOL_API_URL="https://api.knol.io" \
KNOL_USER_ID="test-user" \
npm start

Execute these requests in sequence:

  1. Store a memory (knol_remember):
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_remember",
    "arguments": {
      "content": "Test memory for integration testing"
    }
  }
}

Note the returned memory ID.

  1. Retrieve the memory (knol_get):
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "knol_get",
    "arguments": {
      "memory_id": "mem_xyz123"
    }
  }
}
  1. Update the memory (knol_update):
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "knol_update",
    "arguments": {
      "memory_id": "mem_xyz123",
      "content": "Updated test memory",
      "importance": 8
    }
  }
}
  1. Search for memories (knol_search):
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "knol_search",
    "arguments": {
      "query": "integration testing",
      "limit": 5
    }
  }
}
  1. Delete the memory (knol_delete):
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "knol_delete",
    "arguments": {
      "memory_id": "mem_xyz123"
    }
  }
}

Expected: All operations succeed in sequence.

Test 2: Knowledge Graph Operations

  1. List entities (knol_entities):
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_entities",
    "arguments": {
      "entity_type": "technology",
      "limit": 20
    }
  }
}
  1. Get entity neighbors (knol_entity_neighbors):
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "knol_entity_neighbors",
    "arguments": {
      "entity_id": "ent_123",
      "limit": 10
    }
  }
}

Test 3: Resource Access

Request the recent memories resource:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "resources/list",
  "params": {}
}

Expected: Response includes knol://recent resource.

Then read it:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "resources/read",
  "params": {
    "uri": "knol://recent"
  }
}

Expected: Response with JSON array of recent memories.

Error Testing

Test 1: Invalid API Key

KNOL_API_KEY="invalid_key" npm start

Send any request. Expected: 401 Unauthorized error.

Test 2: Invalid Memory ID

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_get",
    "arguments": {
      "memory_id": "nonexistent_id"
    }
  }
}

Expected: 404 Not Found error.

Test 3: Missing Required Parameters

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_search",
    "arguments": {}
  }
}

Expected: Error about missing required query parameter.

Test 4: Unknown Tool

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_nonexistent",
    "arguments": {}
  }
}

Expected: Error about unknown tool.

Test 5: Unknown Resource

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "resources/read",
  "params": {
    "uri": "knol://nonexistent"
  }
}

Expected: Error about unknown resource.

Performance Testing

Test 1: Large Query Results

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_search",
    "arguments": {
      "query": "common term",
      "limit": 1000
    }
  }
}

Check response time and memory usage.

Test 2: Rapid Requests

for i in {1..100}; do
  echo "Request $i"
  curl -X POST http://localhost:8080/v1/memory/search \
    -H "Authorization: Bearer YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{"query":"test","limit":5}'
done

Monitor for performance degradation.

Test 3: Large Metadata

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "knol_remember",
    "arguments": {
      "content": "Test with large metadata",
      "metadata": {
        "large_field": "x".repeat(10000)
      }
    }
  }
}

Stress Testing

Concurrent Requests

Using Apache Bench:

ab -n 100 -c 10 \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -p request.json \
  http://localhost:8080/v1/memory/search

Load Testing with Artillery

Create load-test.yml:

config:
  target: "http://localhost:8080"
  phases:
    - duration: 60
      arrivalRate: 10
scenarios:
  - name: "Knol API Load Test"
    flow:
      - post:
          url: "/v1/memory/search"
          json:
            query: "test"
            limit: 5
          headers:
            Authorization: "Bearer YOUR_KEY"

Run:

npx artillery run load-test.yml

Local Development Testing

Watch Mode with Testing

npm run dev &
npm run test:watch &

Code Coverage

npm run test:coverage

View coverage report:

open coverage/lcov-report/index.html

CI/CD Testing

GitHub Actions Example

Create .github/workflows/test.yml:

name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v3
        with:
          node-version: '18'

      - run: npm install

      - run: npm run build

      - run: npm test

      - run: npm run test:coverage

      - uses: codecov/codecov-action@v3

Docker Testing

Build Test Image

FROM node:18-alpine

WORKDIR /app
COPY . .

RUN npm install
RUN npm run build

ENTRYPOINT ["npm", "test"]

Build and run:

docker build -t knol-mcp-test .
docker run -e KNOL_API_KEY="test" knol-mcp-test

Debugging

Enable Verbose Logging

export DEBUG=*
npm start

Node Inspector

node --inspect dist/index.js

Then open Chrome DevTools at chrome://inspect.

Console Logging

Add logging to src/index.ts:

console.log("Tool called:", name, args);

Rebuild and test:

npm run build
KNOL_API_KEY="test" npm start | tee server.log

Test Checklist

Reporting Issues

When reporting test failures, include:

  1. Your test command
  2. Expected output
  3. Actual output
  4. Server logs
  5. Environment variables (without secrets)
  6. Node version: node --version
  7. npm version: npm --version

Example:

Test: knol_search with large limit
Command: knol_search (query: "test", limit: 1000)
Expected: Response with up to 1000 results
Actual: Timeout after 30 seconds
Node: v18.0.0
npm: 8.0.0
Logs: [paste relevant logs]