Skip to content

Commit bfeb02e

Browse files
committed
initial commit
0 parents  commit bfeb02e

File tree

16 files changed

+8337
-0
lines changed

16 files changed

+8337
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitignore

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Created by https://www.toptal.com/developers/gitignore/api/node
2+
# Edit at https://www.toptal.com/developers/gitignore?templates=node
3+
4+
### Node ###
5+
# Logs
6+
logs
7+
*.log
8+
npm-debug.log*
9+
yarn-debug.log*
10+
yarn-error.log*
11+
lerna-debug.log*
12+
.pnpm-debug.log*
13+
14+
# Diagnostic reports (https://nodejs.org/api/report.html)
15+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16+
17+
# Runtime data
18+
pids
19+
*.pid
20+
*.seed
21+
*.pid.lock
22+
23+
# Directory for instrumented libs generated by jscoverage/JSCover
24+
lib-cov
25+
26+
# Coverage directory used by tools like istanbul
27+
coverage
28+
*.lcov
29+
30+
# nyc test coverage
31+
.nyc_output
32+
33+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34+
.grunt
35+
36+
# Bower dependency directory (https://bower.io/)
37+
bower_components
38+
39+
# node-waf configuration
40+
.lock-wscript
41+
42+
# Compiled binary addons (https://nodejs.org/api/addons.html)
43+
build/Release
44+
45+
# Dependency directories
46+
node_modules/
47+
jspm_packages/
48+
49+
# Snowpack dependency directory (https://snowpack.dev/)
50+
web_modules/
51+
52+
# TypeScript cache
53+
*.tsbuildinfo
54+
55+
# Optional npm cache directory
56+
.npm
57+
58+
# Optional eslint cache
59+
.eslintcache
60+
61+
# Optional stylelint cache
62+
.stylelintcache
63+
64+
# Microbundle cache
65+
.rpt2_cache/
66+
.rts2_cache_cjs/
67+
.rts2_cache_es/
68+
.rts2_cache_umd/
69+
70+
# Optional REPL history
71+
.node_repl_history
72+
73+
# Output of 'npm pack'
74+
*.tgz
75+
76+
# Yarn Integrity file
77+
.yarn-integrity
78+
79+
# dotenv environment variable files
80+
.env
81+
.env.development.local
82+
.env.test.local
83+
.env.production.local
84+
.env.local
85+
86+
# parcel-bundler cache (https://parceljs.org/)
87+
.cache
88+
.parcel-cache
89+
90+
# Next.js build output
91+
.next
92+
out
93+
94+
# Nuxt.js build / generate output
95+
.nuxt
96+
dist
97+
98+
# Gatsby files
99+
.cache/
100+
# Comment in the public line in if your project uses Gatsby and not Next.js
101+
# https://nextjs.org/blog/next-9-1#public-directory-support
102+
# public
103+
104+
# vuepress build output
105+
.vuepress/dist
106+
107+
# vuepress v2.x temp and cache directory
108+
.temp
109+
110+
# Docusaurus cache and generated files
111+
.docusaurus
112+
113+
# Serverless directories
114+
.serverless/
115+
116+
# FuseBox cache
117+
.fusebox/
118+
119+
# DynamoDB Local files
120+
.dynamodb/
121+
122+
# TernJS port file
123+
.tern-port
124+
125+
# Stores VSCode versions used for testing VSCode extensions
126+
.vscode-test
127+
128+
# yarn v2
129+
.yarn/cache
130+
.yarn/unplugged
131+
.yarn/build-state.yml
132+
.yarn/install-state.gz
133+
.pnp.*
134+
135+
### Node Patch ###
136+
# Serverless Webpack directories
137+
.webpack/
138+
139+
# Optional stylelint cache
140+
141+
# SvelteKit build / generate output
142+
.svelte-kit
143+
144+
# End of https://www.toptal.com/developers/gitignore/api/node
145+

LICENSE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2025 JaxNode User Group, David Fekke
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# JaxNode June 25th MCP example code
2+
3+
This is the sample code for the JaxNode June 2025 presentation on Model Context Protocol.
4+
5+
This example workspace has three projects in the `apps` folder. They are as follows:
6+
7+
* apps/avmxmcpstdio - This is a MCP server running a MCP server using STDIO
8+
* apps/avmxmcpserver - This is MCP server running Express so it can do HTTP Streaming
9+
* apps/avwxchat - This is a Next.js app using a LLM consuming the MCP Server
10+
11+
# Installing the examples
12+
13+
These examples require Node.js 22 or higher and PNPM since this is being run from a PNPM workspace.
14+
15+
To install, run the following command at the root level of the workspace folder:
16+
17+
```sh
18+
$ pnpm install
19+
```
20+
21+
This example uses OpenAI, but you can change this to use any LLM that supports tool calling through Langchain's React and MCP plugins. The default expects an OpenAI API Key. You can get one by going to [https://platform.openai.com/](https://platform.openai.com/), and going to your settings and selecting `API Keys`.
22+
23+
You can either add your API key to your environment variables, but you also rename the `.env.example` to `.env.local`, and setting the `OPENAI_API_KEY="<YOUR_API_KEY>"` to your API key.
24+
25+
To run the example, simply run `pnpm run dev` at the root of the project.
26+
27+
Copyright 2025 JaxNode

apps/.DS_Store

6 KB
Binary file not shown.

apps/avmxmcpstdio/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# JaxNode MCP Example
2+
3+
To test, use the inspector:
4+
5+
```sh
6+
$ npx @modelcontextprotocol/inspector node index.js
7+
```

apps/avmxmcpstdio/index.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3+
import { z } from "zod";
4+
5+
// Create an MCP server
6+
const server = new McpServer({
7+
name: "Aviation Weather",
8+
description: "A server that provides aviation weather information.",
9+
version: "1.0.0"
10+
});
11+
12+
server.tool("get_aviation_weather",
13+
"A tool to get aviation weather information in a METAR format",
14+
{ location: z.string().length(4).describe("The ICAO code of the airport") },
15+
async ({ location }) => {
16+
// Simulate a weather API call
17+
const weatherApiResponse = await fetch(`https://avwx.fekke.com/metar/${location}`);
18+
const weatherData = await weatherApiResponse.json();
19+
return {
20+
content: [{
21+
type: "text",
22+
text: JSON.stringify(weatherData[0], null, 2)
23+
}]
24+
};
25+
}
26+
);
27+
28+
server.tool("get_aviation_weather_forecast",
29+
"A tool to get aviation weather forecast information in a TAR (Terminal Area Forecast) format",
30+
{ location: z.string().length(4).describe("The ICAO code of the airport") },
31+
async ({ location }) => {
32+
// Simulate a weather API call
33+
const weatherApiResponse = await fetch(`https://avwx.fekke.com/taf/${location}`);
34+
const weatherData = await weatherApiResponse.json();
35+
return {
36+
content: [{
37+
type: "text",
38+
text: JSON.stringify(weatherData[0], null, 2)
39+
}]
40+
};
41+
}
42+
);
43+
44+
// Add a dynamic greeting resource
45+
server.resource(
46+
"greeting",
47+
new ResourceTemplate("greeting://{name}", { list: undefined }),
48+
async (uri, { name }) => ({
49+
contents: [{
50+
uri: uri.href,
51+
text: `Hello, ${name}!`
52+
}]
53+
})
54+
);
55+
56+
// Start receiving messages on stdin and sending messages on stdout
57+
const transport = new StdioServerTransport();
58+
await server.connect(transport);

apps/avmxmcpstdio/langchain.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3+
import { ChatOpenAI } from "@langchain/openai";
4+
import { createReactAgent } from "@langchain/langgraph/prebuilt";
5+
import { loadMcpTools } from "@langchain/mcp-adapters";
6+
7+
// Initialize the ChatOpenAI model
8+
const model = new ChatOpenAI({ modelName: "gpt-4.1" });
9+
10+
// Set up the MCP client and transport
11+
const transport = new StdioClientTransport({
12+
command: "node",
13+
args: ["index.js"],
14+
});
15+
16+
const client = new Client({
17+
name: "aviation-weather-client",
18+
version: "1.0.0",
19+
});
20+
21+
try {
22+
// Connect to the MCP server
23+
await client.connect(transport);
24+
25+
// Load tools from the MCP server
26+
const tools = await loadMcpTools("aviation_weather", client, {
27+
throwOnLoadError: true,
28+
prefixToolNameWithServerName: false,
29+
additionalToolNamePrefix: "",
30+
});
31+
32+
// Create and run the agent
33+
const agent = createReactAgent({ llm: model, tools });
34+
const agentResponse = await agent.invoke({
35+
messages: [{ role: "user", content: "What is aviation weather for KJAX" }],
36+
});
37+
console.log(agentResponse);
38+
} catch (e) {
39+
console.error(e);
40+
} finally {
41+
// Clean up the connection
42+
await client.close();
43+
}

apps/avmxmcpstdio/package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "avmxmcpstdio",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "node index.js",
8+
"inspector": "npx @modelcontextprotocol/inspector node index.js",
9+
"langchain": "node langchain.js"
10+
},
11+
"keywords": [],
12+
"author": "",
13+
"license": "ISC",
14+
"dependencies": {
15+
"@langchain/langgraph": "^0.3.4",
16+
"@langchain/mcp-adapters": "^0.5.2",
17+
"@langchain/openai": "^0.5.15",
18+
"@modelcontextprotocol/sdk": "^1.13.0",
19+
"zod": "^3.25.67"
20+
}
21+
}

apps/avwxchat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit eca540146f0199bde9a86d7be36804cf29bf9cc6

0 commit comments

Comments
 (0)