revenuebase-mcp-server
Enables using the RevenueBase MCP server with Python applications through the MCP Python SDK, allowing developers to verify emails and manage batch processing programmatically.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@revenuebase-mcp-serververify john.doe@acmecorp.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
RevenueBase MCP Server
A Model Context Protocol (MCP) server that provides access to RevenueBase's industry-leading email verification API. This server enables AI assistants and applications to verify business emails, including catch-all and firewall-protected domains, with over 99% accuracy.
Features
Real-time Email Verification: Verify individual email addresses instantly
Batch Email Processing: Submit and process large email lists
Process Management: Monitor, cancel, and track batch processing jobs
Credit Management: Check remaining API credits
API Key Management: Generate new API keys
High Accuracy: Over 99% accuracy for B2B email verification
Catch-All Domain Support: Verify catch-all email domains that other tools can't handle
Firewall Navigation: Bypass email firewalls like Mimecast and Barracuda
Related MCP server: json-mcp-server
About RevenueBase
RevenueBase provides industry-leading email verification services specifically built for B2B data providers. With the ability to verify catch-all and firewall-protected domains, RevenueBase ensures maximum accuracy where other services fall short.
Learn more about RevenueBase's email verification services at: https://revenuebase.ai/email-list-cleaning/
Installation
Clone this repository:
git clone https://github.com/avivshafir/revenuebase-mcp-server
cd revenuebase-mcp-serverInstall dependencies using uv:
uv syncSet up your RevenueBase API key:
export REVENUEBASE_API_KEY="your_api_key_here"Usage
Running the Server
python server.pyThe server will start and be available for MCP connections.
Using with MCP Clients
Claude Desktop
To use this server with Claude Desktop, add the following configuration to your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"revenuebase": {
"command": "uv",
"args": ["--directory", "/path/to/revenuebase-mcp-server", "run", "python", "server.py"],
"env": {
"REVENUEBASE_API_KEY": "your_api_key_here"
}
}
}
}Replace /path/to/revenuebase-mcp-server with the actual path to your cloned repository and your_api_key_here with your actual RevenueBase API key.
Other MCP Clients
For other MCP clients, you can connect to the server using the stdio transport. The server runs as a standard MCP server and accepts connections on stdin/stdout.
Example using the MCP Python SDK:
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
server_params = StdioServerParameters(
command="python",
args=["server.py"],
env={"REVENUEBASE_API_KEY": "your_api_key_here"}
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the connection
await session.initialize()
# List available tools
tools = await session.list_tools()
print("Available tools:", [tool.name for tool in tools.tools])
# Call a tool
result = await session.call_tool("real_time_email_verification", {
"email": "test@example.com"
})
print("Verification result:", result)Available Tools
1. Real-time Email Verification
Verify a single email address instantly.
Parameters:
email(string): The email address to verify
Example:
real_time_email_verification("user@example.com")2. Batch Email Submission
Submit a file reference for batch email processing.
Parameters:
filename(string): The filename reference for batch processing
Example:
batch_email_submission("email_list.csv")3. Batch Process Status
Check the status of a batch email processing job.
Parameters:
process_id(int): The ID of the batch processing job
Example:
batch_process_email_status(12345)4. Queued Processes
List all queued email batch processing jobs.
Example:
queued_process()5. Cancel Process
Cancel an ongoing or queued batch email processing job.
Parameters:
process_id(int): The ID of the process to cancel
Example:
cancel_process(12345)6. Get Credits
Retrieve the number of remaining credits for your account.
Example:
get_credits()7. Generate New API Key
Generate and return a new API key.
Example:
new_api_key()Configuration
Environment Variables
REVENUEBASE_API_KEY: Your RevenueBase API key (required)
API Endpoints
The server connects to the following RevenueBase API endpoints:
https://api.revenuebase.ai/v1/process-email- Real-time email verificationhttps://api.revenuebase.ai/v1/batch-process-email- Batch email submissionhttps://api.revenuebase.ai/v1/batch-process-email-status- Batch status checkhttps://api.revenuebase.ai/v1/queued-process- List queued processeshttps://api.revenuebase.ai/v1/cancel-process- Cancel processhttps://api.revenuebase.ai/v1/credits- Get creditshttps://api.revenuebase.ai/v1/new-api-key- Generate new API key
Error Handling
All tools include proper error handling and will raise RuntimeError if the API key is not configured. HTTP errors from the RevenueBase API are automatically raised using requests.raise_for_status().
Requirements
Python 3.7+
fastmcp
requests
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For RevenueBase API support and documentation, visit:
For issues with this MCP server, please open an issue in this repository.
Available Tools
7 toolsbatch_email_submissionC
Submits a file reference for batch email processing using the Revenuebase API.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It mentions 'submits' implying a write operation, but doesn't disclose behavioral traits like whether this is asynchronous, what permissions are required, potential rate limits, or what happens after submission (e.g., does it return a process ID?). The description is minimal and lacks critical operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no wasted words. It's front-loaded with the core action and resource, though it could benefit from slightly more detail without sacrificing brevity. The structure is clear but minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and low parameter coverage, the description is incomplete. It doesn't explain what the tool returns (e.g., success/failure, a process ID), error conditions, or how it integrates with sibling tools. For a submission tool with potential side effects, this leaves significant gaps in understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It only mentions 'file reference' vaguely, without explaining what 'filename' represents (e.g., a local file path, a URL, a pre-uploaded reference). No details on format, constraints, or examples are provided, leaving the parameter poorly defined beyond the schema's basic type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the action ('submits') and resource ('file reference for batch email processing'), but lacks specificity about what the processing entails. It mentions the Revenuebase API, which provides some context, but doesn't clearly differentiate this tool from sibling tools like 'batch_process_email_status' or 'queued_process' that might handle related batch operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. With siblings like 'batch_process_email_status', 'cancel_process', and 'queued_process', the description offers no indication of prerequisites, sequencing, or distinctions between submission and status-checking tools, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_process_email_statusC
Retrieves status of batch email processing job.
| Name | Required | Description | Default |
|---|---|---|---|
| process_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states this is a retrieval operation, implying read-only behavior, but doesn't cover aspects like error handling, rate limits, authentication needs, or what the status output includes (e.g., progress, errors). For a tool with no annotations, this leaves significant gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero waste. It's front-loaded with the core action and resource, making it easy to scan and understand quickly without unnecessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and low schema coverage, the description is incomplete. It lacks details on behavioral traits, parameter usage, and expected return values (e.g., status format, possible states). For a tool that retrieves job status, more context is needed to guide effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It implies the 'process_id' parameter is needed to identify the job, adding some meaning beyond the schema's title ('Process Id'). However, it doesn't explain the parameter's format, source (e.g., from 'batch_email_submission'), or constraints, providing only basic context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Retrieves') and resource ('status of batch email processing job'), making the purpose understandable. However, it doesn't distinguish this tool from potential sibling tools like 'queued_process' or 'cancel_process' that might also relate to batch processing, missing full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description doesn't mention prerequisites (e.g., needing a process_id from a prior job), exclusions, or comparisons to siblings like 'queued_process' or 'batch_email_submission', leaving usage context unclear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_processC
Cancels an ongoing or queued batch email processing job using the Revenuebase API.
| Name | Required | Description | Default |
|---|---|---|---|
| process_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action ('Cancels') but doesn't describe what cancellation entails (e.g., irreversible, partial completion, notifications), error conditions (e.g., invalid ID, already completed), permissions required, or rate limits. This leaves significant gaps for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero waste. It front-loads the key action ('Cancels') and resource, and the mention of 'Revenuebase API' provides useful context without redundancy. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (a mutation tool with no annotations, 0% schema coverage, and no output schema), the description is incomplete. It lacks details on behavior, error handling, prerequisites, and what to expect after cancellation. For a tool that performs a potentially destructive action, this is inadequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 0%, so the description must compensate. It implies a 'process_id' is needed by mentioning 'batch email processing job', but doesn't explain what a process_id is, where to get it, or its format. This adds minimal semantic value beyond the schema's basic structure, resulting in a baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Cancels') and the target resource ('ongoing or queued batch email processing job'), which is specific and actionable. It distinguishes from siblings by focusing on cancellation rather than submission, status checking, or other operations. However, it doesn't explicitly differentiate from all siblings (e.g., 'queued_process' might be related).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing a valid process_id), when cancellation is appropriate (e.g., for jobs in specific states), or what happens if used incorrectly. No explicit alternatives or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_creditsA
Retrieves the number of remaining credits for the authenticated user.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It indicates this is a read operation ('Retrieves'), which is helpful, but doesn't mention potential rate limits, authentication requirements beyond 'authenticated user,' error conditions, or return format. The description adds basic context but lacks detailed behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core purpose with zero wasted words. It immediately communicates what the tool does without unnecessary elaboration, making it easy to parse and understand quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (0 parameters, no output schema), the description is adequate but could be more complete. It explains the purpose clearly but lacks details on return values (e.g., numeric count, object structure), error handling, or dependencies. For a read-only tool with no parameters, this is minimally viable but leaves gaps in behavioral context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters, and schema description coverage is 100% (though empty). The description appropriately doesn't discuss parameters since none exist, which is sufficient for this case. No additional parameter semantics are needed beyond what the schema already indicates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Retrieves') and resource ('number of remaining credits for the authenticated user'), making the tool's purpose immediately understandable. It distinguishes itself from sibling tools which focus on email processing, API keys, and process management rather than credit retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context by specifying 'for the authenticated user,' suggesting this tool should be used when checking credit balances. However, it provides no explicit guidance on when to use this versus alternatives (none of which appear to be credit-related), nor does it mention prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
new_api_keyB
Generates and returns a new API key for the user.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions that it 'Generates and returns' an API key, implying a write operation, but lacks details on permissions needed, rate limits, whether the key is immediately active, or if old keys are invalidated. This leaves significant gaps for a tool that likely involves security-sensitive actions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with no wasted words, making it easy to parse and understand quickly. It's appropriately sized for a simple tool with no parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of generating an API key (a security-sensitive write operation), no annotations, and no output schema, the description is incomplete. It doesn't explain what the returned API key looks like, any associated metadata, or behavioral traits like authentication requirements, making it inadequate for safe and effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description doesn't add parameter details, which is appropriate here, but it could have mentioned if any implicit parameters (like user context) are involved. Baseline is 4 for 0 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Generates and returns') and the resource ('a new API key for the user'), making the purpose immediately understandable. However, it doesn't differentiate from sibling tools, as none appear to be related to API key management, so it doesn't need explicit distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives, prerequisites, or any context about its role among the sibling tools. It simply states what it does without indicating appropriate scenarios or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
queued_processB
Lists all queued email batch processing jobs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool lists jobs, implying a read-only operation, but doesn't specify if it requires authentication, returns paginated results, or includes metadata like timestamps. This leaves gaps in understanding the tool's behavior beyond basic listing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that directly states the tool's function without any fluff or redundancy. It's front-loaded with the core action and resource, making it easy to parse quickly, which is ideal for a simple listing tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (0 parameters, no output schema, no annotations), the description is minimally adequate. It explains what the tool does but lacks details on return format (e.g., list structure, fields) and behavioral context like error handling. For a listing tool with no structured support, more completeness would enhance usability.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description adds no parameter details, which is appropriate here, as there's nothing to compensate for. A baseline of 4 is given since the schema fully covers the absence of parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('Lists') and resource ('queued email batch processing jobs'), making it immediately understandable. However, it doesn't differentiate from sibling tools like 'batch_process_email_status' which might also relate to processing status, leaving room for potential confusion about when to use each.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'batch_process_email_status' or 'cancel_process'. It lacks context about prerequisites, such as whether jobs must be in a specific state, or exclusions, leaving the agent to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
real_time_email_verificationC
Verifies a single email address using the Revenuebase API.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the action ('verifies') but doesn't describe what verification entails (e.g., checks for validity, deliverability, or spam traps), whether it's synchronous or real-time, error handling, or any rate limits. This leaves significant gaps for a tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero waste: 'Verifies a single email address using the Revenuebase API.' It's front-loaded with the core action and appropriately sized for the tool's apparent simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations and output schema, the description is incomplete. It doesn't explain what the verification returns (e.g., status codes, confidence scores) or behavioral aspects like error cases. For a verification tool with no structured context, this leaves the agent under-informed about how to interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 1 parameter with 0% description coverage, so the description must compensate. It mentions 'a single email address' but doesn't specify the format (e.g., valid email syntax) or constraints (e.g., domain requirements). This adds minimal semantic value beyond what's implied by the parameter name 'email'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Verifies a single email address using the Revenuebase API.' It specifies the verb ('verifies'), resource ('a single email address'), and mechanism ('using the Revenuebase API'). However, it doesn't explicitly differentiate from sibling tools like batch_email_submission or batch_process_email_status, which likely handle multiple emails or status checks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention siblings like batch_email_submission for multiple emails or queued_process for asynchronous handling, nor does it specify prerequisites such as API key requirements or rate limits. Usage context is implied but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
- First observed
batch_email_submission - First observed
batch_process_email_status - First observed
cancel_process - First observed
get_credits - First observed
new_api_key - First observed
queued_process - First observed
real_time_email_verification
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose with no overlap: batch_email_submission initiates processing, batch_process_email_status checks status, cancel_process stops jobs, get_credits shows credits, new_api_key generates keys, queued_process lists jobs, and real_time_email_verification verifies single emails. The descriptions reinforce these distinct functions, making tool selection unambiguous.
All tools follow a consistent snake_case naming pattern with clear verb-noun combinations (e.g., batch_email_submission, real_time_email_verification). The naming convention is uniform across all seven tools, making them predictable and easy to understand at a glance.
With 7 tools, this server is well-scoped for email verification and batch processing tasks. Each tool serves a specific, necessary function in the workflow, from initiation to status checks and management, without being overly sparse or bloated.
The tool set covers core email verification and batch processing operations comprehensively, including submission, status retrieval, cancellation, credit management, and API key generation. A minor gap exists in lacking a tool for detailed results of completed batch jobs, but agents can work around this using the status tool.
Maintenance
Related MCP Connectors
MCP server for Product Management
MCP server for medicare-coverage
Related MCP Servers
- -
- MIT
- MIT
- Apache 2.0