vitruvian-man

FABELIS.AI

Elevating

AI

With MCP

in Rust

Scroll To Learn More

The

Mission

We

had

a

few

goals

in

mind

when

creating

this

project.

Remote MCP Connections

AI agents are powerful generative forces, but lack the ability to execute...
Fabelis bridges that gap providing first-class MCP servers allowing remote tool calling. Post a tweet by prompting an agent!

RIG® Compatible

We build RIG, RIG builds us...
LLM applications need strong efficient backbones. Our framework is no exception.

Open Source EXPANSION

With the modularity provided in this repo, anyone can contribute. We provide Interfaces and Guides to help you get started. Check out our social platforms to view any bounties or challenges related to OS contributions!

What's

MCP

?

The

Model

Context

Protocol

is

the

API

Layer

for

Agents

Schema Built by Anthropic

Remote Tools

Communicate with remote tools on demand

Data Resources

Fetch remote data and resources

Always available

Prompt Templates

Leverage established prompt templating

Token holders receive exclusive benefits
Early access for verified token holders

Our

Resources

Look

at

what

we

have

to

offer.

Feel

free

to

contribute.

The

Tech

You

get

it?

Come

on

now,

lets

see

what

it

can

do!

twitter.rs
1pub async fn start(&mut self) { 2 info!("[TWITTER] Starting client with 15s delay..."); 3 let (sender, mut receiver) = mpsc::channel(3); 4 5 let post_sender = sender.clone(); 6 let post_config = self.config.clone(); 7 tokio::spawn(async move { 8 sleep(std::time::Duration::from_secs(15)).await; 9 loop { 10 if post_sender.send(Action::Post()).await.is_err() { 11 break; 12 } 13 14 let delay = rand::thread_rng() 15 .gen_range(post_config.post_delay[0]..=post_config.post_delay[1]); 16 info!("[TWITTER][POST] sleeping for {} minutes", delay); 17 sleep(std::time::Duration::from_secs(u64::from(delay) * 60)).await; 18 } 19 }); 20 21 let reply_sender = sender.clone(); 22 let reply_config = self.config.clone(); 23 tokio::spawn(async move { 24 sleep(std::time::Duration::from_secs(15)).await; 25 loop { 26 if reply_sender.send(Action::Reply()).await.is_err() { 27 break; 28 } 29 30 let delay = rand::thread_rng() 31 .gen_range(reply_config.reply_delay[0]..=reply_config.reply_delay[1]); 32 info!("[TWITTER][REPLY] sleeping for {} minutes", delay); 33 sleep(std::time::Duration::from_secs(u64::from(delay) * 60)).await; 34 } 35 }); 36 37 while let Some(action) = receiver.recv().await { 38 match action { 39 Action::Post() => { 40 info!("[TWITTER][POST] Executing..."); 41 let topic = self 42 .character 43 .choose_random_traits(crate::core::CharacterTrait::Topics, 1); 44 45 self.search(&topic).await; 46 47 sleep(std::time::Duration::from_secs( 48 u64::from(self.config.search_delay) * 60, 49 )) 50 .await; 51 52 self.post(topic).await; 53 } 54 Action::Reply() => info!("[TWITTER][REPLY] Executing..."), 55 } 56 sleep(std::time::Duration::from_secs(u64::from(self.config.delay))).await; 57 } 58 }

Easy-to-use Examples

Easily configure your own FABELIS agent instance using our examples and quick start guides. Fork our repository and get started in under 5 minutes.

Click Here

rig.rs
1use dotenv::dotenv; 2use mcp_core::{ 3 client::Client, 4 transport::{ClientSseTransport, Transport}, 5 types::Implementation, 6}; 7use std::{env, sync::Arc}; 8 9use mcp_rig::{completion::Prompt, providers}; 10 11const DISCORD_SERVER_URL: &str = "https://discord-mcp.fabelis.ai"; 12const TWITTER_SERVER_URL: &str = "https://twitter-mcp.fabelis.ai"; 13 14#[tokio::main] 15async fn main() -> Result<(), anyhow::Error> { 16 tracing_subscriber::fmt().init(); 17 18 dotenv().ok(); 19 20 let transport = ClientSseTransport::builder(TWITTER_SERVER_URL.to_string()).build(); 21 transport.open().await?; 22 23 let mcp_client = Arc::new( 24 Client::builder(transport) 25 .with_secure_value( 26 "twitter_api_key", 27 mcp_core::client::SecureValue::Env("TWITTER_API_KEY".to_string()), 28 ) 29 .with_secure_value( 30 "twitter_api_secret", 31 mcp_core::client::SecureValue::Env("TWITTER_API_SECRET".to_string()), 32 ) 33 .with_secure_value( 34 "twitter_access_token", 35 mcp_core::client::SecureValue::Env("TWITTER_ACCESS_TOKEN".to_string()), 36 ) 37 .with_secure_value( 38 "twitter_access_token_secret", 39 mcp_core::client::SecureValue::Env("TWITTER_ACCESS_TOKEN_SECRET".to_string()), 40 ) 41 .use_strict() 42 .build(), 43 ); 44 let mcp_client_clone = mcp_client.clone(); 45 tokio::spawn(async move { mcp_client_clone.start().await }); 46 47 let init_res = mcp_client 48 .initialize(Implementation { 49 name: "mcp-client".to_string(), 50 version: "0.1.0".to_string(), 51 }) 52 .await?; 53 println!("Initialized: {:?}", init_res); 54 55 let tools_list_res = mcp_client.list_tools(None, None).await?; 56 println!("Tools: {:?}", tools_list_res); 57 58 tracing::info!("Running RIG example"); 59 60 let openai_client = providers::openai::Client::new( 61 &env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set"), 62 ); 63 64 let mut agent_builder = openai_client.agent("gpt-4o") 65 // Use preamble to allow for secure values to be used in the tool call 66 .preamble("If a tool says fields can use a null value do not ask the user for those values and default them to an empty strings because the MCP Client will add them automatically."); 67 68 // Add MCP tools to the agent 69 agent_builder = tools_list_res 70 .tools 71 .into_iter() 72 .fold(agent_builder, |builder, tool| { 73 builder.mcp_tool(tool, mcp_client.clone()) 74 }); 75 let agent = agent_builder.build(); 76 77 let response = agent.prompt("Post 'hello' on twitter").await?; 78 tracing::info!("Agent response: {:?}", response); 79 80 Ok(()) 81}

Rust MCP Servers

Our signature product offering are our Rust MCP servers. Fully compatible with both RIG and any other MCP client of your choice, out of the box

Click Here

The Future of FABELIS

FABELIS constantly strives for new innovations. You can view the latest updates of our roadmap and our future on our Social Platforms.

Click Here

"MODULARITY IS KING"

FABELIS

FABELIS.AI 2025