SignalK MCP服务器
一种模型上下文协议(MCP)服务器,为AI代理提供对SignalK海洋数据的高效访问,使用 V8隔离中的代码执行这种方法通过以下方式减少了令牌的使用 90-96% 与传统的MCP工具相比。
🚀 版本1.0.6:现在使用代码执行引擎来节省大量代币!看 更改日志.md 了解详情。
为什么要执行代码?
传统的MCP工具将所有数据返回给AI,消耗大量代币。此服务器使用 V8隔离 (如Cloudflare Workers)让AI代理运行过滤数据的JavaScript代码 之前 返回它。
代币节省:
- 船舶状态查询: 减少94% (2,000 → 120 代币)
- AIS目标过滤: 减少95% (10,000 → 500 代币)
- 多呼叫工作流程: 减少97% (13,000 → 300 代币)
快速开始
安装
# Via npx (recommended)
npx signalk-mcp-server
# Or install globally
npm install -g signalk-mcp-serverClaude桌面配置
添加到您的Claude桌面配置(~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):
{
"mcpServers": {
"signalk": {
"command": "npx",
"args": ["signalk-mcp-server"],
"env": {
"SIGNALK_HOST": "localhost",
"SIGNALK_PORT": "3000",
"SIGNALK_TLS": "false"
}
}
}
}基本用法
AI代理查询: “我的船的位置和3个最近的AIS目标是什么?”
代码执行(自动):
(async () => {
// Get vessel position
const vessel = await getVesselState();
const position = vessel.data["navigation.position"]?.value;
// Get AIS targets and filter in isolate
const ais = await getAisTargets({ pageSize: 50 });
const closest = ais.targets.slice(0, 3);
return JSON.stringify({ position, closest });
})()
// Returns: ~300 tokens (97% savings vs legacy tools!)特性
代码执行引擎
- V8隔离沙盒:安全的JavaScript执行
- 客户端过滤:在返回AI之前处理数据
- 多个API调用:在一次执行中组合操作
- 90-96%的代币节省:大幅减少上下文窗口的使用
- 1000米以下高空:具有内存/超时限制的快速执行
可用的SDK功能
使用时 execute_code,这些功能可用。 重要提示:所有函数都是异步的,必须等待:
// Vessel data
const vessel = await getVesselState();
// AIS targets (with pagination and optional distance filter)
const ais = await getAisTargets({ page: 1, pageSize: 50, maxDistance: 5000 });
// System alarms
const alarms = await getActiveAlarms();
// Discover available data paths
const paths = await listAvailablePaths();
// Get specific path value (both string and object syntax work)
const speed = await getPathValue("navigation.speedOverGround");
const heading = await getPathValue({ path: "navigation.headingTrue" });
// Connection status - ALSO requires await!
const status = await getConnectionStatus();实时海洋数据
- 船舶位置、航向、速度、风
- AIS目标跟踪与距离计算
- 系统通知和警报
- 动态SignalK路径发现
- 连接健康监测
配置
环境变量
# SignalK Connection (Required)
SIGNALK_HOST=localhost # SignalK server hostname/IP
SIGNALK_PORT=3000 # SignalK server port
SIGNALK_TLS=false # Use WSS/HTTPS (true/false)
# Execution Mode (Optional)
EXECUTION_MODE=code # code (default) | tools (legacy) | hybrid
# Optional Settings
SERVER_NAME=signalk-mcp-server
SERVER_VERSION=1.0.6执行模式
| 模式 | 描述 | 用例 |
|---|---|---|
| 代码 (默认) | 仅V8隔离执行 | 生产使用,最高效率 |
| 工具 | 传统MCP工具 | 向后兼容性 |
| 混合 | 两种方法都可用 | 迁移期 |
示例
示例1:过滤后的船舶数据
查询: “获取我的船名和位置”
代码:
(async () => {
const vessel = await getVesselState();
return JSON.stringify({
name: vessel.data.name?.value,
position: vessel.data["navigation.position"]?.value
});
})()结果: 约200个代币(使用传统工具时为2000个)
示例2:附近的船只
查询: “显示1海里以内的船只”
代码:
(async () => {
const ais = await getAisTargets({ pageSize: 50 });
// Filter in isolate - huge savings!
const nearby = ais.targets.filter(t =>
t.distanceMeters && t.distanceMeters {
const alarms = await getActiveAlarms();
const critical = alarms.alarms.filter(a =>
a.state === "alarm" || a.state === "emergency"
);
return JSON.stringify({
hasCritical: critical.length > 0,
count: critical.length,
details: critical
});
})()结果: 约100个代币(而传统工具为1000个)
示例4:多呼叫工作流
查询: “给我一份情况报告”
代码:
(async () => {
// All calls in ONE execution!
const vessel = await getVesselState();
const ais = await getAisTargets({ pageSize: 50 });
const alarms = await getActiveAlarms();
// Process everything in isolate
const closeVessels = ais.targets.filter(t =>
t.distanceMeters && t.distanceMeters
a.state === "alarm" || a.state === "emergency"
).length;
return JSON.stringify({
position: vessel.data["navigation.position"]?.value,
speed: vessel.data["navigation.speedOverGround"]?.value,
vesselsNearby: closeVessels,
criticalAlarms: criticalAlarms
});
})()结果: 约300个令牌(相比之下,13000个令牌有3个单独的工具调用!)
发展
先决条件
- Node.js 18.0.0或更高版本
- 访问SignalK服务器
设置
# Clone repository
git clone
cd signalk-mcp-server
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm run test:unit
# Run in development mode
npm run dev测试
# Unit tests (fast)
npm run test:unit
# Integration tests (requires live SignalK server)
npm run test:e2e
# Full CI pipeline
npm run ci建筑
代码执行流程
AI Agent
↓
execute_code tool
↓
V8 Isolate Sandbox (isolated-vm)
↓
SignalK SDK Functions (all async, must await)
↓
SignalK Binding Layer (RPC-style)
↓
SignalK Client (HTTP REST API)
↓
SignalK Server注: 仅HTTP模式确保每个请求都有新的数据。WebSocket代码保留用于未来的流媒体支持。
关键组件
- 隔离沙箱 (
src/execution-engine/isolate-sandbox.ts):确保V8隔离执行 - SignalK绑定 (
src/bindings/signalk-binding.ts):RPC样式的方法调用 - SDK生成器 (
src/sdk/generator.ts):根据工具定义自动生成SDK - SignalK客户端 (
src/signalk-client.ts):SignalK的HTTP/WebSocket客户端
安全
- 完全隔离:无法访问Node.js全局变量
- 内存限制:每次执行128MB
- 超时保护:30秒最大执行时间
- 无凭证风险:绑定层处理SignalK身份验证
- 只读的:不对SignalK服务器进行写入操作
从1.x迁移
突破性变化
1.0.6版本将默认模式从 hybrid 到 code默认情况下,传统工具不再可用。
向后兼容
要使用传统工具,请设置执行模式:
{
"mcpServers": {
"signalk": {
"env": {
"EXECUTION_MODE": "tools"
}
}
}
}迁移指南
看 工具-绘图指南.md 查看完整的迁移示例。
之前(遗留):
Tool: get_vessel_state
Returns: All vessel data (~2000 tokens)之后(代码):
(async () => {
const vessel = await getVesselState();
return JSON.stringify({
name: vessel.data.name?.value,
position: vessel.data["navigation.position"]?.value
});
})()
// Returns: ~200 tokens故障排除
连接问题
检查连接状态(注意: await 必填):
(async () => {
const status = await getConnectionStatus(); // await is required!
return JSON.stringify(status);
})()传统模式
如果您暂时需要旧版工具:
EXECUTION_MODE=tools npx signalk-mcp-server调试模式
启用详细日志记录:
DEBUG=true
LOG_LEVEL=debug贡献
欢迎投稿!请看 贡献.md 作为指导方针。
许可证
MIT许可证-请参阅 许可证 了解详情。
资源
- SignalK文件
- 模型上下文协议
- 更改日志.md -版本历史和迁移指南
- 工具-绘图指南.md -详细的迁移示例
- 克劳德桌面MCP文档
鸣谢
内置:
- 隔离虚拟机 -V8隔离执行
- @模型上下文协议/sdk -MCP TypeScript SDK
- SignalK社区提供卓越的海洋数据协议
______________________________________________________________________
🚢 用人工智能驱动的海洋数据快乐航行!
