MicroCore is a collection of Python adapters for Large Language Models and Vector Databases / Semantic Search APIs that lets you communicate with these services in a convenient way, makes them easily switchable, and separates business logic from the implementation details.
It defines interfaces for features typically used in AI applications, which allows you to keep your application as simple as possible and try various models & services without the need to change your application code.
You can even switch between text completion and chat completion models using only configuration.
Thanks to LLM-agnostic MCP integration, MicroCore connects MCP tools to any language models easily, whether through API providers that do not support MCP, or through inference using PyTorch or arbitrary Python functions.
The basic example of usage is as follows:
from microcore import llm
while user_msg := input('Enter message: '):
print('AI: ' + llm(user_msg))Install as a PyPI package:
pip install ai-microcore
Alternatively, you may just copy microcore folder to your project sources root.
git clone git@github.com:Nayjest/ai-microcore.git && mv ai-microcore/microcore ./ && rm -rf ai-microcorePython 3.10 / 3.11 / 3.12 / 3.13 / 3.14
Having OPENAI_API_KEY in OS environment variables is enough for basic usage.
Similarity search features will work out of the box if you have the chromadb pip package installed.
There are a few options available for configuring microcore:
- Use
microcore.configure(**params)
💡 All configuration options appear in IDE autocompletion tooltips - Create a
.envfile in your project root; examples: basic.env, Mistral Large.env, Anthropic Claude.env, Gemini on Vertex AI.env, Gemini on AI Studio.env - Use a custom configuration file:
mc.configure(DOT_ENV_FILE='dev-config.ini') - Define OS environment variables
For the full list of available configuration options, you may also check
microcore/configuration.py
(see the LLMConfig and Config dataclasses).
For models that work via APIs other than the OpenAI API, you may need to install additional packages:
pip install anthropicpip install google-genaipip install azure-identity azure-identity-brokerInference with Entra requires RBAC on the AI resource (for example Cognitive Services User at resource scope; for some deployments Cognitive Services OpenAI User applies). Owner/Contributor does not substitute for these roles. Role assignments can take several minutes to propagate.
Microsoft guide: Configure Microsoft Entra ID for Azure AI Foundry models.
Configuration example: .env.azure-openai-entra-id.example
By default, MicroCore uses the Chat Completions API for OpenAI-compatible providers.
Set LLM_USE_RESPONSES_API=true to use the Responses API
instead (required for some Azure OpenAI deployments and models available only via /responses).
You will need to install transformers and a deep learning library of your choice (PyTorch, TensorFlow, Flax, etc.).
See transformers installation.
You can run inference through any external command-line LLM tool
(e.g. claude, gemini, ...)
by setting LLM_API_TYPE to ApiType.CLI and providing the command in LLM_CLI.
The <request> placeholder is replaced with the prompt, and the tool's stdout is
streamed back as the response (so streaming callbacks work as usual).
import microcore as mc
mc.configure(
LLM_API_TYPE=mc.ApiType.CLI,
LLM_CLI="claude -p <request>",
)
print(mc.llm("What is the capital of France?"))The same via a .env file:
LLM_API_TYPE=cli
LLM_CLI="gemini --skip-trust -p <request>"No API key is required. A non-zero exit code from the tool raises CommandLineLLMError.
Ready-to-use configuration examples: .env.claude-code.example, .env.gemini-cli.example
- Configuration options passed as arguments to
microcore.configure()have the highest priority. - The priority of configuration file options (
.envby default or the value ofDOT_ENV_FILE) is higher than OS environment variables.
💡 SettingUSE_DOT_ENVtofalsedisables reading configuration files. - OS environment variables have the lowest priority.
The test-llm command validates a configuration file against the live API:
python -m microcore test-llm <.env-file> [<prompt>]It issues a single completion request; without a custom prompt, it asks for the capital of France
and verifies the answer. Exit code 0 indicates success; 1 indicates a configuration error,
request failure, or unexpected response.
Vector database functions are available via microcore.texts.
The default vector database is Chroma.
In order to use vector database functions with ChromaDB, you need to install the chromadb package:
pip install chromadbBy default, MicroCore will use ChromaDB PersistentClient (if the corresponding package is installed). Alternatively, you can run Chroma as a separate service and configure MicroCore to use HttpClient:
from microcore import configure
configure(
EMBEDDING_DB_HOST = 'localhost',
EMBEDDING_DB_PORT = 8000,
)In order to use vector database functions with Qdrant, you need to install the qdrant-client package:
pip install qdrant-clientConfiguration example:
from microcore import configure, EmbeddingDbType
from sentence_transformers import SentenceTransformer
configure(
EMBEDDING_DB_TYPE=EmbeddingDbType.QDRANT,
EMBEDDING_DB_HOST="localhost",
EMBEDDING_DB_PORT="6333",
EMBEDDING_DB_SIZE=384, # number of dimensions in the SentenceTransformer model
EMBEDDING_DB_FUNCTION=SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2"),
)Performs a request to a large language model (LLM).
Asynchronous variant: allm(prompt: str, **kwargs)
from microcore import *
# Will print all requests and responses to console
use_logging()
# Basic usage
ai_response = llm('What is your model name?')
# You may also pass a list of strings as prompt
# - For chat completion models elements are treated as separate messages
# - For completion LLMs elements are treated as text lines
llm(['1+2', '='])
llm('1+2=', model='gpt-5.6')
# To specify a message role, you can use dictionary or classes
llm(dict(role='system', content='1+2='))
# equivalent
llm(SysMsg('1+2='))
# The returned value is a string
assert '7' == llm([
SysMsg('You are a calculator'),
UserMsg('1+2='),
AssistantMsg('3'),
UserMsg('3+4=')]
).strip()
# But it contains all fields of the LLM response in additional attributes
for i in llm('1+2=?', n=3, temperature=2).choices:
print('RESPONSE:', i.message.content)
# To use response streaming you may specify the callback function:
llm('Hi there', callback=lambda x: print(x, end=''))
# Or multiple callbacks:
output = []
llm('Hi there', callbacks=[
lambda x: print(x, end=''),
lambda x: output.append(x),
])Renders prompt template with params.
Full-featured Jinja2 templates are used by default.
Related configuration options:
from microcore import configure
configure(
# 'tpl' folder in current working directory by default
PROMPT_TEMPLATES_PATH = 'my_templates_folder'
)texts.search(collection: str, query: str | list, n_results: int = 5, where: dict = None, **kwargs) → SearchResults
Similarity search. Returned items are strings (SearchResult)
with additional attributes: id, distance, metadata.
Alias: texts.find(...); texts.find_all(...) returns all matching documents (no n_results limit).
Optional where filters results by metadata (ChromaDB-style operators).
Supported on both Chroma and Qdrant:
from microcore import texts
# Equality
texts.search("docs", "revenue", where={"id": "5_12"})
# Match any of the listed values
texts.search("docs", "revenue", where={"id": {"$in": ["5_12", "5_13"]}})
# Combine predicates
texts.search(
"docs",
"revenue",
where={"$and": [{"type": "measure"}, {"id": {"$in": ["5_12", "5_13"]}}]},
)
texts.search(
"docs",
"revenue",
where={"$or": [{"id": "5_12"}, {"domain_id": "5_13"}]},
)
# Nested groups (e.g. allow-list AND an $or of item types)
texts.search(
"docs",
"revenue",
where={
"$and": [
{"$or": [{"item_type": "measure"}, {"item_type": "dimension"}]},
{"id": {"$in": ["5_12", "5_13"]}},
]
},
)where is optional - when omitted, search is unfiltered. Passing a raw
qdrant_client.http.models.Filter as where is also supported for Qdrant.
Find most similar text
texts.get(collection: str, ids: list[str] | str = None, limit: int = None, offset: int = None, where: dict = None, **kwargs)
Get documents by id / metadata filter without similarity search.
Uses the same where operators as texts.search ($eq / plain equality, $in, $and, $or).
Return all texts in the collection
Store text and related metadata in embeddings database.
If id is not provided, it will be generated.
Store multiple texts and related metadata in the embeddings database.
Each item may be a string (text), a (text, metadata) tuple, or a (text, metadata, id) tuple.
If id is not provided, it will be generated.
Count documents in the collection
Delete documents by id, list of ids, or metadata filter
(same where operators when what is a dict).
Clear collection
MicroCore connects MCP tool servers to any LLM backend, including providers without native MCP support (the tool definitions are rendered into the prompt, and tool calls are parsed from the model output).
import asyncio
from microcore import allm, mcp, configure
configure()
async def main():
question = "What documentation topics exist for the fastapi/fastapi repository?"
# DeepWiki: public MCP server answering questions about GitHub repositories
server = await mcp.MCPServer("https://mcp.deepwiki.com/mcp").connect()
tool_call = await allm(
f"{question}\n"
f"Answer with a call to one of the following tools and nothing else.\n{server.tools}"
)
data = await server.exec(tool_call)
print(await allm([question, data]))
asyncio.run(main())MCP servers may also be predefined in configuration via MCP_SERVERS and accessed
by name through mcp_server(name). See working examples:
one-shot tool call,
agent loop,
using MCP with various LLMs.
MicroCore supports major API providers via various chat completion / text completion APIs.
Tested with the following services:
- OpenAI
- Anthropic (via Anthropic API and via OpenAI API)
- MistralAI
- Google AI Studio (via Google GenAI API and via OpenAI API)
- Google Vertex AI
- xAI
- Microsoft Azure
- Perplexity
- DeepSeek
- Cohere
- RunPod (via OpenAI API)
- Cerebras
- HuggingFace Inference API
- AI21 Studio
- Deep Infra
- Anyscale
- Groq
- Fireworks
- Together AI
- OpenRouter
- 01.AI
And more via Google / Anthropic / OpenAI API.
- HuggingFace Transformers (see configuration examples here).
- Command-line LLM tools (e.g.
llm,ollama,claude,gemini) viaApiType.CLI(see Inference via a command-line tool). - Custom local models by providing own function for chat / text completion, sync / async inference.
Performs a code review by LLM for changes in git .patch files in any programming language.
Image analysis (Google Colab)
Determine the number of petals and the color of the flower from a photo (gpt-4-turbo)
Benchmark LLMs on math problems (Kaggle Notebook)
Benchmark accuracy of 20+ state-of-the-art models on solving olympiad math problems. Inferencing local language models via HuggingFace Transformers, parallel inference.
Simple example demonstrating image generation using OpenAI GPT Image model.
Text generation using HF/Transformers model locally (example with Qwen 3 0.6B).
For more detailed information, check out these articles:
Usage Example:
from microcore.ai_func import ai_func
@ai_func
def search_products(
query: str,
category: str = "all",
max_results: int = 10,
in_stock_only: bool = False
):
"""
Search for products in the catalog.
Args:
query: Search terms to find matching products
category: Product category to filter by (e.g., "electronics", "clothing")
max_results: Maximum number of results to return
in_stock_only: If True, only return products currently in stock
Returns:
List of matching products with name, price, and availability
"""
# Implementation would go here
passOutput:
# Search for products in the catalog.
Args:
query: Search terms to find matching products
category: Product category to filter by (e.g., "electronics", "clothing")
max_results: Maximum number of results to return
in_stock_only: If True, only return products currently in stock
Returns:
List of matching products with name, price, and availability
{
"call": "search_products",
"query": <str>,
"category": <str> (default = "all"),
"max_results": <int> (default = 10),
"in_stock_only": <bool> (default = False)
}
This is an experimental feature.
Tweaks the Python import system to provide automatic setup of MicroCore environment based on metadata in module docstrings.
import microcore.ai_modules- Automatically registers template folders of AI modules in Jinja2 environment
Please see CONTRIBUTING for details.
Licensed under the MIT License © 2023–2026 Vitalii Stepanenko