Skip to main content
Glama
karan19

NexusNote MCP Server

by karan19

MCP Server

MCP-compatible WebSocket server with a companion Amplify-ready React frontend. Use the commands below to run locally, build containers, or deploy to AWS.

Local Development

cd mcp npm install export SERPAPI_KEY=<your-serpapi-key> export COGNITO_REGION=<aws-region> export COGNITO_USER_POOL_ID=<user-pool-id> export COGNITO_USER_POOL_CLIENT_ID=<app-client-id> export BEDROCK_REGION=<aws-region> export BEDROCK_MODEL_ID=anthropic.claude-3-haiku-20240307-v1:0 npm run dev # hot-reload server # npm run build # compile to dist/ # npm run start:websocket # run compiled output

The server listens on 0.0.0.0:8080. Modify src/config/env.ts if you need different bindings.

Optional environment overrides:

  • BEDROCK_MAX_OUTPUT_TOKENS (default 512)

  • BEDROCK_TEMPERATURE (default 0.2)

  • MCP_HOST / MCP_PORT

  • MCP_DYNAMODB_TABLE_CONFIG (semicolon-separated entries table|partitionKey|sortKey|gsiName|gsiPartitionKey|gsiSortKey)

  • MCP_CHAT_TABLE_NAME (optional table selector when multiple entries are supplied)

  • TOOL_METRICS_EMIT_EMF (set to true to emit CloudWatch Embedded Metric Format logs for tool calls)

Frontend (Amplify-ready)

# from repo root cp apps/frontend/.env.example apps/frontend/.env # edit VITE_API_BASE_URL to point at your MCP service # populate Cognito settings: VITE_COGNITO_REGION, VITE_COGNITO_USER_POOL_ID, VITE_COGNITO_USER_POOL_CLIENT_ID npm run dev:frontend # start Vite dev server npm run build:frontend # production build (outputs to apps/frontend/dist)

Deploy with AWS Amplify Hosting by connecting this repo and keeping the generated amplify.yml. The build pipeline runs npm ci at the repo root and publishes apps/frontend/dist. Set VITE_API_BASE_URL, VITE_COGNITO_REGION, VITE_COGNITO_USER_POOL_ID, and VITE_COGNITO_USER_POOL_CLIENT_ID in Amplify’s environment settings.

Optional frontend flags:

  • VITE_CHAT_USE_STREAMING=true enables the SSE-based /chat/stream endpoint so the UI can show live status updates while the assistant thinks.

Chat API & persistence

The MCP server exposes a small REST surface alongside the /chat orchestrator endpoint:

Endpoint

Method

Description

/chat

POST

Execute the next turn in a conversation. Accepts { message, sessionId?, messageId? }. Returns { sessionId, reply, toolCalls }.

/chat/stream

POST (SSE)

Same payload as /chat, but set Accept: text/event-stream to receive status and tool-call updates as Server-Sent Events.

/conversations

GET

List conversation summaries for the authenticated user.

/conversations/:id/messages

GET

Retrieve the full message history for a session (ordered by createdAt).

/conversations/search

GET

Search prior chat messages using a DynamoDB scan scoped to the authenticated user.

/metrics

GET

Prometheus text-format metrics (tool success/failure counters, retries, circuit state).

External tool calls (SerpAPI, Wikipedia, arXiv) automatically retry with exponential backoff, short-term caching, and circuit breakers to soften upstream outages.

Chat history is stored in DynamoDB. Provide table metadata via MCP_DYNAMODB_TABLE_CONFIG, for example:

export MCP_DYNAMODB_TABLE_CONFIG="mcp-chat|sessionId|createdAt|userIndex|userId|lastMessageAt"

The table uses:

  • PK: sessionId

  • SK: ISO timestamp for messages, __SUMMARY__ for the summary item

  • GSI (optional but recommended): userIndex on userId / lastMessageAt for listing conversations by user

Set MCP_CHAT_TABLE_NAME when multiple tables are defined and you need to select the chat store explicitly.

When you deploy via the provided CDK stack, leave MCP_CREATE_CHAT_TABLE=true to have the chat history table (and its userIndex GSI) created automatically. Use MCP_CHAT_TABLE_NAME if you need to control the physical table name; the stack wires both MCP_DYNAMODB_TABLE_CONFIG and MCP_CHAT_TABLE_NAME into the service task definition.

Docker Image

cd mcp docker build -t mcp-server .

AWS Deployment (manual)

  1. Set deployment config

    cd mcp/infrastructure cp .env.example .env # edit .env with your account ID, Cognito pool/client, Bedrock model, etc.

    Key variables:

    • MCP_ACCOUNT_ID, MCP_REGION

    • MCP_COGNITO_USER_POOL_ID, MCP_COGNITO_USER_POOL_CLIENT_ID

    • MCP_BEDROCK_MODEL_ID (defaults to meta.llama3-8b-instruct-v1:0)

    • MCP_SERPAPI_SECRET_NAME (Secrets Manager entry containing the SerpAPI key)

    • MCP_DYNAMODB_TABLE_ARNS (comma-separated DynamoDB table ARNs the service may read)

    • MCP_DYNAMODB_TABLE_CONFIG (semicolon-separated table descriptors table|partitionKey|sortKey|gsiName|gsiPartitionKey|gsiSortKey)

    • MCP_CREATE_CHAT_TABLE (defaults to true; set to false to skip provisioning the managed chat table)

    • MCP_CHAT_TABLE_NAME (optional explicit name when provisioning the managed chat table)

    • Optional: configure a custom domain directly in the App Runner console after deployment (not automated by this stack yet).

  2. Bootstrap (first time per account/region)

cd mcp/infrastructure npm install npx cdk bootstrap
  1. Create the SerpAPI secret (once)

    aws secretsmanager create-secret \ --name nexusnote/mcp/search-api \ --secret-string "<YOUR_SERPAPI_KEY>"
  2. Deploy – make sure Docker is running locally.

    cd mcp/infrastructure npm install # safe to re-run npm run build # compile CDK app npm run synth # optional: inspect CloudFormation npm run deploy # deploys the McpStack stack

    The deploy step builds a Docker image locally and provisions an App Runner service. If Docker isn’t running you’ll see Cannot connect to the Docker daemon .... After a successful deploy, note the ServiceHttpsUrl output; use it for REST calls and replace the https:// prefix with wss:// when configuring WebSocket clients.

  3. Pause/resume to control cost (optional)

    SERVICE_ARN=<AppRunnerServiceArn from outputs> aws apprunner pause-service --service-arn "$SERVICE_ARN" aws apprunner resume-service --service-arn "$SERVICE_ARN"

App Runner bills only while the service is running. Pausing is the easiest way to keep the monthly cost under a dollar when you only need the tooling a few hours per month.

  1. Teardown (optional)

    cd mcp/infrastructure

npm run destroy

> **App Runner replacements:** App Runner service names must be unique. The stack explicitly sets the service name to `McpStack`, so when CloudFormation needs to *replace* (not update) the service it first tries to create a new one with the same name while the old one still exists. App Runner rejects that with “Service with the provided name already exists”. If you receive that error, delete the existing App Runner service named `McpStack` (console or `aws apprunner delete-service --service-arn ...`) and rerun the deploy. Normal in-place updates continue to work without manual steps. ## Useful Commands Summary | Purpose | Command(s) | |------------------------------|------------| | Local MCP dev | `npm run dev` | | Build MCP TypeScript | `npm run build` | | Start compiled MCP server | `npm run start:websocket` | | Frontend dev server | `npm run dev:frontend` | | Frontend production build | `npm run build:frontend` | | Build Docker image | `docker build -t mcp-server .` | | Deploy MCP infra to AWS | `npm run build && npm run deploy` (from `infrastructure/`) | | Destroy AWS stack | `npm run destroy` (from `infrastructure/`) |
-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/karan19/mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server