Skip to content

Commit e4d00d4

Browse files
authored
Align JavaScript SDK with existing Python SDK (#1)
Add JavaScript/TypeScript SDK for mcpd JavaScript/TypeScript SDK for interacting with the mcpd daemon, providing natural JavaScript syntax for MCP server management and tool execution. Based on Python SDK patterns with JavaScript idioms. API * client.listServers() - List all configured servers * client.getServerHealth(name?) - Get health status for one or all servers * client.isServerHealthy(name) - Check if specific server is healthy * client.servers.foo.listTools() - List tools available on server * client.servers.foo.callTool(name, args) - Dynamic tool invocation * client.servers.foo.hasTool(name) - Check if tool exists on server * client.servers.foo.tools.bar(args) - Direct tool invocation via proxy * client.getToolSchemas(options?) - Get tool schemas with transformed names (serverName__toolName) * client.getAgentTools(options?) - Generate callable functions for AI frameworks Features * Dynamic proxy-based tool access with natural JavaScript syntax * Dual CommonJS/ESM module format support * AI framework integration (LangChain JS, Vercel AI SDK) * Type-safe function generation from MCP tool schemas * Comprehensive error handling with typed exceptions * Health-based server filtering with parallel tool fetching * Built-in caching for health checks and tool schemas * Full TypeScript support with generated type definitions Implementation * Zod-based JSON Schema conversion for framework compatibility * Dependency injection architecture for testability * LRU cache with TTL for health and server data * Structured error handling with ErrorModel parsing * True private methods using JavaScript # syntax * Optimized parallel fetching with Promise.allSettled * Complete test coverage (70 tests) Documentation * Comprehensive README with API examples * LangChain integration example * Vercel AI SDK integration example * Basic usage example * Security policy and code of conduct * Contributing guidelines Tooling * ESLint 9 with flat config * Prettier formatting * Vitest for testing * Vite for building * TypeScript strict mode * CI workflows for testing and linting * GitHub Actions publish workflow Requirements * Node.js 22+ (LTS) * mcpd daemon running Co-authored-by: Khaled Osman <[email protected]>
1 parent d64e99a commit e4d00d4

40 files changed

+11978
-9
lines changed

.github/workflows/lint.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Lint and Format
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
lint:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
19+
with:
20+
node-version: '22'
21+
22+
- name: Install dependencies
23+
run: npm ci
24+
25+
- name: Run linting and typecheck
26+
run: npm run lint
27+
28+
- name: Run formatting
29+
run: npm run format
30+
31+
- name: Check for uncommitted changes
32+
run: |
33+
if [ -n "$(git status --porcelain)" ]; then
34+
echo "Error: Files were modified by formatting. Please run 'npm run format' locally and commit the changes."
35+
git status --porcelain
36+
git diff
37+
exit 1
38+
fi

.github/workflows/release.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Publish to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: "Tag to release (e.g. v0.0.1)"
10+
required: true
11+
12+
jobs:
13+
publish:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
id-token: write # Required for provenance
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Checkout release tag
25+
run: |
26+
git fetch --tags
27+
TAG="${{ github.event.release.tag_name || github.event.inputs.tag }}"
28+
if [ -z "$TAG" ]; then
29+
echo "Error: No tag provided in release event or workflow_dispatch input"
30+
exit 1
31+
fi
32+
echo "Checking out tag $TAG"
33+
git checkout "$TAG"
34+
35+
- name: Setup Node.js
36+
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
37+
with:
38+
node-version: '22'
39+
registry-url: 'https://registry.npmjs.org'
40+
41+
- name: Install dependencies
42+
run: npm ci
43+
44+
- name: Build package
45+
run: npm run build
46+
47+
- name: Publish to npm
48+
run: npm publish --provenance --access public
49+
env:
50+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/tests.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Unit Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
19+
with:
20+
node-version: '22'
21+
22+
- name: Install dependencies
23+
run: npm ci
24+
25+
- name: Run tests
26+
run: npm test
27+
28+
- name: Build package
29+
run: npm run build

.gitignore

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Dependencies
2+
node_modules/
3+
npm-debug.log*
4+
yarn-debug.log*
5+
yarn-error.log*
6+
7+
# Build outputs
8+
dist/
9+
build/
10+
*.tsbuildinfo
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Coverage directory used by tools like istanbul
19+
coverage/
20+
*.lcov
21+
22+
# nyc test coverage
23+
.nyc_output
24+
25+
# ESLint cache
26+
.eslintcache
27+
28+
# Microbundle cache
29+
.rpt2_cache/
30+
.rts2_cache_cjs/
31+
.rts2_cache_es/
32+
.rts2_cache_umd/
33+
34+
# Optional REPL history
35+
.node_repl_history
36+
37+
# Output of 'npm pack'
38+
*.tgz
39+
40+
# Yarn Integrity file
41+
.yarn-integrity
42+
43+
# dotenv environment variables file
44+
.env
45+
.env.local
46+
.env.development.local
47+
.env.test.local
48+
.env.production.local
49+
50+
# parcel-bundler cache (https://parceljs.org/)
51+
.cache
52+
.parcel-cache
53+
54+
# Next.js build output
55+
.next
56+
57+
# Nuxt.js build / generate output
58+
.nuxt
59+
60+
# Gatsby files
61+
.cache/
62+
public
63+
64+
# Storybook build outputs
65+
.out
66+
.storybook-out
67+
68+
# Temporary folders
69+
tmp/
70+
temp/
71+
72+
# Logs
73+
logs
74+
*.log
75+
76+
# Editor directories and files
77+
.vscode/
78+
.idea/
79+
*.swp
80+
*.swo
81+
*~
82+
83+
# OS generated files
84+
.DS_Store
85+
.DS_Store?
86+
._*
87+
.Spotlight-V100
88+
.Trashes
89+
ehthumbs.db
90+
Thumbs.db
91+
92+
# TypeScript cache
93+
*.tsbuildinfo
94+
95+
# Optional eslint cache
96+
.eslintcache
97+
98+
# Optional stylelint cache
99+
.stylelintcache

CODE_OF_CONDUCT.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as
6+
contributors and maintainers pledge to making participation in our project and
7+
our community a harassment-free experience for everyone, regardless of age, body
8+
size, disability, ethnicity, sex characteristics, gender identity and expression,
9+
level of experience, education, socio-economic status, nationality, personal
10+
appearance, race, religion, or sexual identity and orientation.
11+
12+
## Our Standards
13+
14+
Examples of behavior that contributes to creating a positive environment
15+
include:
16+
17+
- Using welcoming and inclusive language
18+
- Being respectful of differing viewpoints and experiences
19+
- Gracefully accepting constructive criticism
20+
- Focusing on what is best for the community
21+
- Showing empathy towards other community members
22+
23+
Examples of unacceptable behavior by participants include:
24+
25+
- The use of sexualized language or imagery and unwelcome sexual attention or
26+
advances
27+
- Trolling, insulting/derogatory comments, and personal or political attacks
28+
- Public or private harassment
29+
- Publishing others' private information, such as a physical or electronic
30+
address, without explicit permission
31+
- Other conduct which could reasonably be considered inappropriate in a
32+
professional setting
33+
34+
## Our Responsibilities
35+
36+
Project maintainers are responsible for clarifying the standards of acceptable
37+
behavior and are expected to take appropriate and fair corrective action in
38+
response to any instances of unacceptable behavior.
39+
40+
Project maintainers have the right and responsibility to remove, edit, or
41+
reject comments, commits, code, wiki edits, issues, and other contributions
42+
that are not aligned to this Code of Conduct, or to ban temporarily or
43+
permanently any contributor for other behaviors that they deem inappropriate,
44+
threatening, offensive, or harmful.
45+
46+
## Scope
47+
48+
This Code of Conduct applies both within project spaces and in public spaces
49+
when an individual is representing the project or its community. Examples of
50+
representing a project or community include using an official project e-mail
51+
address, posting via an official social media account, or acting as an appointed
52+
representative at an online or offline event. Representation of a project may be
53+
further defined and clarified by project maintainers.
54+
55+
## Enforcement
56+
57+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
58+
reported by contacting the team at mozilla.ai. All
59+
complaints will be reviewed and investigated and will result in a response that
60+
is deemed necessary and appropriate to the circumstances. The project team is
61+
obligated to maintain confidentiality with regard to the reporter of an incident.
62+
Further details of specific enforcement policies may be posted separately.
63+
64+
Project maintainers who do not follow or enforce the Code of Conduct in good
65+
faith may face temporary or permanent repercussions as determined by other
66+
members of the project's leadership.
67+
68+
## Attribution
69+
70+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72+
73+
[homepage]: https://www.contributor-covenant.org
74+
75+
For answers to common questions about this code of conduct, see
76+
https://www.contributor-covenant.org/faq

0 commit comments

Comments
 (0)