An MCP server that lets an AI agent reach your local AWS, Azure, GCP and OCI, and the Docker recipes, through two to five tools (about 1K tokens) with reads and writes kept apart. The curated tools below are the named alternative. Recipes are the Docker stacks it can start for you.
Unofficial community project. Not affiliated with or endorsed by the Floci project. Floci does the emulation; this server only talks to it. Support floci-io/floci.
The generic toolset can address every operation in the boto3 service models (~18,000) and reaches
Azure, GCP, OCI and the Docker recipes, with five tools. What answers is what Floci emulates:
list_services(probe=true) shows which AWS services do. The code toolset does the same by running Python,
so a task that chains calls or filters a big result costs one round trip.
search_operations("send a message to a queue") # -> sqs.SendMessage (write)
describe_operation("aws", "sqs", "SendMessage") # parameters, required ones marked
call_write("aws", "sqs", "SendMessage",
{"QueueUrl": "...", "MessageBody": "hi"})
code_read("""
buckets = aws("s3", "ListBuckets")["Buckets"]
topics = call("gcp", "pubsub", "ListTopics")
result = {"s3": len(buckets), "gcp": topics["body"]}
""")
| arm | tools | ~tokens |
|---|---|---|
| curated, default | 90 | 9,300 |
| curated, all | 135 | 15,600 |
generic | 5 | 940 |
code | 2 | 580 |
Reads and writes are separate tools, so FLOCI_READ_ONLY=1 removes the writer. The rule is also enforced
inside the gateway: code_read cannot write whatever the code says. Classification is default-deny and is tested against every
operation of every service model. Secret values need FLOCI_ALLOW_SECRET_VALUES=1.
Recipes cost no context. ListRecipes marks the ones Floci already emulates natively
(RDS for postgres, ElastiCache for redis...), checked against your running Floci.
DeployRecipe waits for RUNNING and moves a taken default port to a free one.
The code sandbox is a guardrail, not isolation. Point it at local emulators only, never at a real cloud.
The tools are the hands. Skills are the playbook: short instructions an agent loads on demand that say which tools to call, in what order, and when to stop and ask. Install them and the agent stops guessing.
/plugin marketplace add pmaojo/floci-mcp-unofficial /plugin install floci@floci-mcp-unofficialor just the skills
mkdir -p ~/.claude/skills ln -s "$PWD"/skills/* ~/.claude/skills/ # or cp -R skills/* ~/.claude/skills/
A skill that needs a toolset which is not enabled by default says so. Ask for it with
FLOCI_TOOLSETS and restart the server.
git clone https://github.com/pmaojo/floci-mcp-unofficial cd floci-mcp-unofficial uv sync && uv run python floci_mcp.py
Needs Python 3.10+, uv and a running Floci. Docker for recipes.
By default it registers the default toolsets only; set FLOCI_TOOLSETS=all for everything, or FLOCI_READ_ONLY=1 to drop every tool that writes.
{
"mcpServers": {
"floci": {
"command": "uv",
"args": ["run", "--project", "/path/to/floci-mcp-unofficial",
"python", "/path/to/floci-mcp-unofficial/floci_mcp.py"],
"env": {
"AWS_ENDPOINT_URL": "http://localhost:4566",
"FLOCI_AZURE_ENDPOINT": "http://localhost:4577",
"FLOCI_GCP_ENDPOINT": "http://localhost:4588",
"FLOCI_OCI_ENDPOINT": "http://localhost:4599"
}
}
}
}
Things to say to the agent, and what it ends up calling. If a toolset is missing, the agent switches it on.
agent (Claude, Cursor, Codex, ...)
| MCP over stdio
v
floci_mcp.py -- toolsets decide which tools are registered
|
|-- boto3 ----------------------------> Floci core :4566 (AWS)
|-- REST (per provider) --------------> Floci-AZ :4577
| Floci-GCP :4588
| Floci-OCI :4599
`-- in-process backend
|-- aws CLI run_local_aws_cmd, Glue catalog, Lambda deploy
`-- docker compose marketplace, pipeline --> recipes/
These are the messages the server returns.
Only if you keep the curated toolsets
suggest_toolsets142 tools in 10 toolsets. Which ones does this task need? The generic and code toolsets make the question unnecessary.
apply=true and the toolsets switch themselves on. It's like magic, but with HTTP.FLOCI_DECIDER=openrouter-jev OPENROUTER_API_KEY=... uv run python floci_mcp.py
*Tested end to end against a very convincing fake, not yet against a live provider. Needs an API key.
The probabilities are the model's, not ours. The OpenRouter path is alpha. Not a substitute for reading the tool list.
May contain nouls (that is what the request calls a yes/no).
A client sends every tool definition on every conversation, and models pick worse among many similar tools. Only the enabled toolsets are registered.
| toolset | tools | default |
|---|
FLOCI_TOOLSETS=core,storage # only these FLOCI_TOOLSETS=all # everything FLOCI_READ_ONLY=1 # drop every tool that writes FLOCI_TOOLSETS_ALLOWED=ops # optional cap; unset: the agent may enable any
| cloud | port | covers |
|---|---|---|
| AWS | 4566 | the full surface, through boto3 |
| Azure | 4577 | data plane plus 15 ARM resource types that answer (storage, SQL, Redis, VMs, AKS...) |
| GCP | 4588 | 20 APIs, 2,283 operations from Google's discovery documents; 70 list reads verified |
| OCI | 4599 | all 8 services: list, get, create, delete |
| recipes | Docker | 35 local stacks, reached as the cloud recipes |
Start with list_clouds: it says which runtimes answer.
| variable | default |
|---|---|
| AWS_ENDPOINT_URL | http://localhost:4566 |
| FLOCI_AZURE_ENDPOINT | http://localhost:4577 |
| FLOCI_GCP_ENDPOINT | http://localhost:4588 |
| FLOCI_OCI_ENDPOINT | http://localhost:4599 |
| FLOCI_TOOLSETS | core,storage,messaging,compute |
| FLOCI_TOOLSETS_ALLOWED | all toolsets |
| FLOCI_READ_ONLY | off |
| SIDECAR_STATE_DIR | ~/.floci-mcp |
FLOCI_READ_ONLY=1 removes them; annotations let a client confirm first.get_secret_value (AWS) does return the value.run_local_aws_cmd is full aws CLI access: a command can pass its own --endpoint-url.proxy_http_request requests any URL from the host.list_toolsets returns a SHA-256 of every registered definition: pin it and compare after updates.hybrid, off at the start, but an agent may enable it unless you cap it with FLOCI_TOOLSETS_ALLOWED.