Skip to content
This repository was archived by the owner on Feb 18, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Eyevinn Open Source Cloud MCP Server

[![smithery badge](https://smithery.ai/badge/@osaas/mcp-server)](https://smithery.ai/server/@osaas/mcp-server)

This MCP server provides MCP tools for [Eyevinn Open Source Cloud](www.osaas.io) that requires local computer access, for example to upload a file to a storage bucket in OSC. MCP tools for architecting and building solutions with OSC is provided by the remote MCP endpoint that can be accessed using the [OSC remote MCP client](https://www.npmjs.com/package/@osaas/client-mcp).
Expand Down Expand Up @@ -45,7 +46,7 @@ To use this with Claude Desktop, add the following to your `claude_desktop_confi
"env": {
"OSC_ACCESS_TOKEN": "<YOUR_TOKEN>"
}
}
}
}
}
```
Expand Down
40 changes: 40 additions & 0 deletions src/resources/minio_minio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,43 @@ export async function uploadFileToMinioBucket(
);
return uploadedObject;
}

export async function listFilesInMinioBucket(
endpoint: string,
accessKeyId: string,
secretAccessKey: string,
bucket: string
): Promise<string[]> {
const minioClient = new Minio.Client({
endPoint: new URL(endpoint).hostname,
accessKey: accessKeyId,
secretKey: secretAccessKey
});

const objects = await minioClient.listObjects(bucket, '', true);
const fileList: string[] = [];
for await (const obj of objects) {
fileList.push(obj.name);
}
return fileList;
}

export async function createMinioBucket(
endpoint: string,
accessKeyId: string,
secretAccessKey: string,
bucket: string
): Promise<void> {
const minioClient = new Minio.Client({
endPoint: new URL(endpoint).hostname,
accessKey: accessKeyId,
secretKey: secretAccessKey
});

const bucketExists = await minioClient.bucketExists(bucket);
if (!bucketExists) {
await minioClient.makeBucket(bucket);
} else {
throw new Error(`Bucket ${bucket} already exists`);
}
}
20 changes: 20 additions & 0 deletions src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,23 @@ export const UploadFileSchema = z.object({
});

export type UploadFileSchema = z.infer<typeof UploadFileSchema>;

export const ListFilesSchema = z.object({
name: z
.string()
.regex(/^[a-z0-9]+$/)
.describe('Name of the minio instance'),
bucket: z.string().describe('Name of the bucket')
});

export type ListFilesSchema = z.infer<typeof ListFilesSchema>;

export const CreateBucketSchema = z.object({
name: z
.string()
.regex(/^[a-z0-9]+$/)
.describe('Name of the minio instance'),
bucket: z.string().describe('Name of the bucket to create')
});

export type CreateBucketSchema = z.infer<typeof CreateBucketSchema>;
92 changes: 90 additions & 2 deletions src/tools/osc.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { zodToJsonSchema } from 'zod-to-json-schema';
import { z } from 'zod';
import { UploadFileSchema } from '../schemas.js';
import {
CreateBucketSchema,
ListFilesSchema,
UploadFileSchema
} from '../schemas.js';
import { Context } from '@osaas/client-core';
import { CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
import {
createMinioBucket,
getMinioInstance,
listFilesInMinioBucket,
uploadFileToMinioBucket
} from '../resources/minio_minio.js';

Expand All @@ -15,6 +21,18 @@
description:
'Upload a file to Eyevinn Open Source Cloud Storage (OSC) Minio instance',
inputSchema: zodToJsonSchema(UploadFileSchema)
},
{
name: 'osc_list_files',
description:
'List files in a bucket on Eyevinn Open Source Cloud Storage (OSC) Minio instance',
inputSchema: zodToJsonSchema(ListFilesSchema)
},
{
name: 'osc_create_bucket',
description:
'Create a new bucket on Eyevinn Open Source Cloud Storage (OSC) Minio instance',
inputSchema: zodToJsonSchema(CreateBucketSchema)
}
];
}
Expand All @@ -31,7 +49,7 @@
switch (request.params.name) {
case 'osc_upload_file': {
const args = UploadFileSchema.parse(request.params.arguments);
const uploaded = await uploadFile(

Check warning on line 52 in src/tools/osc.ts

View workflow job for this annotation

GitHub Actions / ts

'uploaded' is assigned a value but never used
args.name,
args.bucket,
args.objectKey,
Expand All @@ -39,7 +57,43 @@
context
);
return {
toolResult: `File ${args.file} uploaded to s3://${args.bucket}/${args.objectKey} on Minio instance '${args.name}' (${uploaded.etag})`
content: [
{
type: 'text',
text: `File '${args.file}' uploaded to bucket '${args.bucket}' with object key '${args.objectKey}' on Minio instance '${args.name}'.`
}
]
};
}

case 'osc_list_files': {
const args = ListFilesSchema.parse(request.params.arguments);
const files = await listFiles(args.name, args.bucket, context);
return {
content: [
{
type: 'text',
text: `Files in bucket '${args.bucket}' on MinIO instance '${args.name}':`
}
].concat(
files.map((file) => ({
type: 'text',
text: file
}))
)
};
}

case 'osc_create_bucket': {
const args = CreateBucketSchema.parse(request.params.arguments);
await createBucket(args.name, args.bucket, context);
return {
content: [
{
type: 'text',
text: `Bucket '${args.bucket}' created on MinIO instance '${args.name}'.`
}
]
};
}

Expand Down Expand Up @@ -79,3 +133,37 @@
file
);
}

export async function listFiles(
name: string,
bucket: string,
context: Context
) {
const instance = await getMinioInstance(context, name);
if (!instance) {
throw new Error(`Minio instance with name ${name} not found`);
}
return await listFilesInMinioBucket(
instance.endpoint,
instance.accessKeyId,
instance.secretAccessKey,
bucket
);
}

export async function createBucket(
name: string,
bucket: string,
context: Context
) {
const instance = await getMinioInstance(context, name);
if (!instance) {
throw new Error(`Minio instance with name ${name} not found`);
}
return await createMinioBucket(
instance.endpoint,
instance.accessKeyId,
instance.secretAccessKey,
bucket
);
}