Skip to content

Commit

Permalink
add github action
Browse files Browse the repository at this point in the history
  • Loading branch information
0xrinegade committed Jan 22, 2025
1 parent a254ba5 commit 3e28b57
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 234 deletions.
83 changes: 83 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Release

on:
push:
tags:
- 'v*'

jobs:
build-and-release:
name: Build and Release
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: solana-mcp-server
asset_name: solana-mcp-server-linux-amd64
- os: macos-latest
target: x86_64-apple-darwin
artifact_name: solana-mcp-server
asset_name: solana-mcp-server-macos-amd64
- os: macos-latest
target: aarch64-apple-darwin
artifact_name: solana-mcp-server
asset_name: solana-mcp-server-macos-arm64
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: solana-mcp-server.exe
asset_name: solana-mcp-server-windows-amd64.exe

steps:
- uses: actions/checkout@v3

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Build
run: |
cargo build --release --target ${{ matrix.target }}
- name: Prepare asset
shell: bash
run: |
mkdir -p release
if [ "${{ matrix.os }}" = "windows-latest" ]; then
cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} release/${{ matrix.asset_name }}
else
cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} release/${{ matrix.asset_name }}
chmod +x release/${{ matrix.asset_name }}
fi
- name: Upload Release Asset
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: release/${{ matrix.asset_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

create-release:
name: Create Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Get version from tag
id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT

- name: Create Release
id: create_release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
name: Release ${{ steps.get_version.outputs.VERSION }}
draft: false
prerelease: false
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 5 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,14 @@ edition = "2021"

[dependencies]
anyhow = "1.0"
async-trait = "0.1"
base64 = "0.21"
bincode = "1.3"
bs58 = "0.5"
clap = { version = "4.4", features = ["derive"] }
ctrlc = "3.4"
mcp-sdk = "0.0.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
solana-account-decoder = "1.17"
tokio = { version = "1.0", features = ["full"] }
solana-client = "1.17"
solana-sdk = "1.17"
solana-account-decoder = "1.17"
solana-transaction-status = "1.17"
spl-token = "4.0"
tokio = { version = "1.32", features = ["full"] }
base64 = "0.21"
bs58 = "0.5"
bincode = "1.3"
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,28 @@

A Model Context Protocol (MCP) server that provides comprehensive access to Solana blockchain data through Cline. This server implements a wide range of Solana RPC methods, making it easy to query blockchain information directly through natural language conversations.

## Install in Claude Desktop
## Installation

### Using Pre-built Binaries

1. Go to the [Releases](https://github.com/opensvm/solana-mcp-server/releases) page
2. Download the appropriate binary for your system:
- Linux: `solana-mcp-server-linux-amd64`
- macOS Intel: `solana-mcp-server-macos-amd64`
- macOS Apple Silicon: `solana-mcp-server-macos-arm64`
- Windows: `solana-mcp-server-windows-amd64.exe`
3. Make the binary executable (Linux/macOS):
```bash
chmod +x solana-mcp-server-*
```
4. Configure Claude Desktop:
```bash
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/claude"
mkdir -p "$CONFIG_DIR"
echo "{\"mcpServers\":{\"solana\":{\"command\":\"$PWD/solana-mcp-server-*\",\"env\":{\"SOLANA_RPC_URL\":\"https://api.mainnet-beta.solana.com\"}}}}" > "$CONFIG_DIR/config.json"
```

### Building from Source

```bash
TEMP_DIR=$(mktemp -d) && cd "$TEMP_DIR" && git clone https://github.com/opensvm/solana-mcp-server.git . && cargo build --release && CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/claude" && mkdir -p "$CONFIG_DIR" && echo "{\"mcpServers\":{\"solana\":{\"command\":\"$PWD/target/release/solana-mcp-server\",\"env\":{\"SOLANA_RPC_URL\":\"https://api.mainnet-beta.solana.com\"}}}}" > "$CONFIG_DIR/config.json" || { rm -rf "$TEMP_DIR"; exit 1; }
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod rpc;
pub mod server;
pub mod tools;
pub mod transport;

pub use server::start_server;
pub use transport::CustomStdioTransport;
12 changes: 1 addition & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
use anyhow::Result;
use clap::Parser;
use solana_mcp_server::start_server;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Config {
#[arg(long)]
iam_agent: bool,
}

#[tokio::main]
async fn main() -> Result<()> {
let _config = Config::parse();
start_server().await
solana_mcp_server::server::start_server().await
}
33 changes: 19 additions & 14 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
use anyhow::Result;
use std::io::{self, BufRead, Write};
use crate::transport::{Transport, JsonRpcMessage};
use crate::CustomStdioTransport;
use serde_json::Value;

pub async fn start_server() -> Result<()> {
eprintln!("Solana MCP server ready - {} v{}",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
);

let stdin = io::stdin();
let mut stdout = io::stdout();
let mut reader = stdin.lock();
let mut line = String::new();
let transport = CustomStdioTransport::new();
transport.open()?;

loop {
line.clear();
match reader.read_line(&mut line) {
Ok(0) => continue,
Ok(_) => {
if !line.trim().is_empty() {
let response = crate::tools::handle_request(&line).await?;
writeln!(stdout, "{}", serde_json::to_string_pretty(&response)?)?;
stdout.flush()?;
match transport.receive() {
Ok(message) => {
let message_str = serde_json::to_string(&message)?;
let response = crate::tools::handle_request(&message_str).await?;
transport.send(&response)?;
}
Err(e) => {
if e.to_string().contains("Connection closed") {
eprintln!("Client disconnected");
break;
}
eprintln!("Error receiving message: {}", e);
}
Err(e) => eprintln!("Error reading input: {}", e),
}
}

transport.close()?;
Ok(())
}
Loading

0 comments on commit 3e28b57

Please sign in to comment.