Summary
Build translate-graphql from scratch in Rust - a GraphQL-to-MCP bridge that exposes GraphQL APIs as MCP tools with automatic schema introspection and query generation.
Motivation
GraphQL is increasingly popular for APIs. A Rust-native GraphQL bridge provides:
- High-performance query parsing and validation
- Efficient schema introspection and caching
- Automatic MCP tool generation from GraphQL types
Rust Benefits
| Aspect |
Python (graphql-core) |
Rust (async-graphql/juniper) |
| Query parsing |
~5K queries/s |
~200K queries/s |
| Schema introspection |
~100ms |
~5ms |
| Query validation |
~2K/s |
~100K/s |
| Memory per schema |
~10MB |
~500KB |
Key Improvements
- Fast query parsing with Rust's parser combinators
- Efficient schema representation - compact in-memory model
- Native async - tokio integrates naturally with GraphQL resolvers
- Type-safe query building - Rust's type system catches errors at compile time
Proposed Architecture
┌─────────────────────────────────────────────────────────┐
│ MCP Gateway (Python) │
├─────────────────────────────────────────────────────────┤
│ PyO3 Bridge │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────┐ │
│ │ translate-graphql (Rust) │ │
│ ├─────────────────────────────────────────────────┤ │
│ │ ┌───────────┐ ┌───────────┐ ┌─────────────┐ │ │
│ │ │ Schema │ │ Query │ │ MCP │ │ │
│ │ │Introspect │ │ Builder │ │ Mapper │ │ │
│ │ └───────────┘ └───────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ Rust Core │
├─────────────────────────────────────────────────────────┤
│ GraphQL Endpoints │
└─────────────────────────────────────────────────────────┘
Core Components
1. Schema Introspection
use graphql_parser::schema::{parse_schema, Document};
use reqwest::Client;
pub struct GraphQLSchema {
types: HashMap<String, TypeDefinition>,
queries: Vec<FieldDefinition>,
mutations: Vec<FieldDefinition>,
}
impl GraphQLSchema {
pub async fn introspect(endpoint: &str) -> Result<Self> {
let client = Client::new();
let response = client
.post(endpoint)
.json(&introspection_query())
.send()
.await?;
let schema_data: IntrospectionResult = response.json().await?;
Self::from_introspection(schema_data)
}
}
2. MCP Tool Generation
impl GraphQLSchema {
/// Convert GraphQL queries/mutations to MCP tools
pub fn to_mcp_tools(&self) -> Vec<McpTool> {
let mut tools = Vec::new();
// Convert queries
for query in &self.queries {
tools.push(McpTool {
name: format!("graphql_query_{}", query.name),
description: query.description.clone(),
input_schema: self.args_to_json_schema(&query.arguments),
});
}
// Convert mutations
for mutation in &self.mutations {
tools.push(McpTool {
name: format!("graphql_mutation_{}", mutation.name),
description: mutation.description.clone(),
input_schema: self.args_to_json_schema(&mutation.arguments),
});
}
tools
}
}
3. Query Execution
pub struct GraphQLBridge {
schema: GraphQLSchema,
endpoint: String,
client: Client,
}
impl GraphQLBridge {
pub async fn execute_tool(&self, tool_name: &str, args: Value) -> Result<Value> {
let (operation_type, field_name) = parse_tool_name(tool_name)?;
// Build GraphQL query from MCP tool call
let query = self.build_query(operation_type, field_name, &args)?;
// Execute query
let response = self.client
.post(&self.endpoint)
.json(&GraphQLRequest { query, variables: args })
.send()
.await?;
let result: GraphQLResponse = response.json().await?;
Ok(result.data)
}
fn build_query(&self, op: OperationType, field: &str, args: &Value) -> String {
// Generate GraphQL query string with proper field selection
}
}
4. Type Mapping
| GraphQL Type |
JSON Schema |
MCP |
String |
{"type": "string"} |
string |
Int |
{"type": "integer"} |
integer |
Float |
{"type": "number"} |
number |
Boolean |
{"type": "boolean"} |
boolean |
ID |
{"type": "string"} |
string |
[Type] |
{"type": "array", "items": ...} |
array |
Type! |
required field |
required |
InputObject |
{"type": "object", "properties": ...} |
object |
Enum |
{"enum": [...]} |
enum |
Crates to Use
graphql-parser - GraphQL query/schema parsing
reqwest - HTTP client
serde_json - JSON handling
tokio - async runtime
pyo3 - Python bindings
Features
Acceptance Criteria
Example Usage
from mcpgateway.rust import GraphQLBridge
# Initialize bridge
bridge = GraphQLBridge("https://api.example.com/graphql")
await bridge.introspect()
# Get MCP tools
tools = bridge.get_tools()
# [McpTool(name="graphql_query_users", ...), McpTool(name="graphql_mutation_createUser", ...)]
# Execute tool
result = await bridge.execute("graphql_query_users", {"limit": 10})
References
Summary
Build
translate-graphqlfrom scratch in Rust - a GraphQL-to-MCP bridge that exposes GraphQL APIs as MCP tools with automatic schema introspection and query generation.Motivation
GraphQL is increasingly popular for APIs. A Rust-native GraphQL bridge provides:
Rust Benefits
Key Improvements
Proposed Architecture
Core Components
1. Schema Introspection
2. MCP Tool Generation
3. Query Execution
4. Type Mapping
String{"type": "string"}Int{"type": "integer"}Float{"type": "number"}Boolean{"type": "boolean"}ID{"type": "string"}[Type]{"type": "array", "items": ...}Type!InputObject{"type": "object", "properties": ...}Enum{"enum": [...]}Crates to Use
graphql-parser- GraphQL query/schema parsingreqwest- HTTP clientserde_json- JSON handlingtokio- async runtimepyo3- Python bindingsFeatures
Acceptance Criteria
Example Usage
References