Skip to main content
Glama
zeph-to

@zeph-to/mcp-server

by zeph-to

zeph_file

Upload and deliver text content such as logs, reports, or code snippets as a file push to the user's device.

Instructions

Send a text file to the user's device. The content is uploaded and delivered as a file push. Use for logs, reports, code snippets, or any text content.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fileNameYesFile name with extension (e.g., "report.txt", "output.json")
contentYesText content of the file
titleNoNotification title (defaults to fileName)
targetDeviceIdNoTarget device ID. Omit to use configured default or send to all devices.

Implementation Reference

  • The main handler function for the zeph_file tool. It: 1) infers MIME type from filename, 2) requests an upload URL from the API, 3) uploads the content to S3, 4) sends a file push notification to the target device.
      async ({ fileName, content, title, targetDeviceId }) => {
        try {
          const fileType = inferMimeType(fileName);
          const fileSize = new TextEncoder().encode(content).byteLength;
    
          // Step 1: Request upload URL
          const upload = await client.requestUpload({ fileName, fileType, fileSize });
    
          // Step 2: Upload content to S3
          await client.uploadToS3(upload.data.uploadUrl, content, fileType);
    
          // Step 3: Send file push
          const result = await client.sendPush({
            title: title ?? fileName,
            type: 'file',
            files: [{ fileKey: upload.data.fileKey, fileName, fileSize, fileType }],
            targetDeviceId: targetDeviceId ?? config.deviceId,
          });
    
          return textResult({ pushId: result.data.pushId, fileKey: upload.data.fileKey, fileSize });
        } catch (err) {
          return formatToolError(err);
        }
      },
    );
  • Input schema for the zeph_file tool: fileName (string, required), content (string, required), title (string, optional), targetDeviceId (string, optional).
    inputSchema: {
      fileName: z.string().describe('File name with extension (e.g., "report.txt", "output.json")'),
      content: z.string().describe('Text content of the file'),
      title: z.string().optional().describe('Notification title (defaults to fileName)'),
      targetDeviceId: z.string().optional().describe('Target device ID. Omit to use configured default or send to all devices.'),
    },
  • src/tools/file.ts:7-50 (registration)
    The registerFileTool function that registers the tool with the MCP server under the name 'zeph_file' with description, annotations, input schema, and the handler callback.
    export const registerFileTool = (server: McpServer, client: ZephApiClient, config: McpServerConfig) => {
      server.registerTool(
        'zeph_file',
        {
          description:
            'Send a text file to the user\'s device. The content is uploaded and delivered as a file push. Use for logs, reports, code snippets, or any text content.',
          annotations: {
            readOnlyHint: false,
            destructiveHint: false,
            openWorldHint: true,
          },
          inputSchema: {
            fileName: z.string().describe('File name with extension (e.g., "report.txt", "output.json")'),
            content: z.string().describe('Text content of the file'),
            title: z.string().optional().describe('Notification title (defaults to fileName)'),
            targetDeviceId: z.string().optional().describe('Target device ID. Omit to use configured default or send to all devices.'),
          },
        },
        async ({ fileName, content, title, targetDeviceId }) => {
          try {
            const fileType = inferMimeType(fileName);
            const fileSize = new TextEncoder().encode(content).byteLength;
    
            // Step 1: Request upload URL
            const upload = await client.requestUpload({ fileName, fileType, fileSize });
    
            // Step 2: Upload content to S3
            await client.uploadToS3(upload.data.uploadUrl, content, fileType);
    
            // Step 3: Send file push
            const result = await client.sendPush({
              title: title ?? fileName,
              type: 'file',
              files: [{ fileKey: upload.data.fileKey, fileName, fileSize, fileType }],
              targetDeviceId: targetDeviceId ?? config.deviceId,
            });
    
            return textResult({ pushId: result.data.pushId, fileKey: upload.data.fileKey, fileSize });
          } catch (err) {
            return formatToolError(err);
          }
        },
      );
    };
  • src/index.ts:66-66 (registration)
    Registration call in the main server setup: registerFileTool(server, client, config) wires the tool into the MCP server.
    registerFileTool(server, client, config);
  • Helper function inferMimeType that maps file extensions to MIME types (e.g., .txt→text/plain, .json→application/json). Defaults to text/plain.
    const inferMimeType = (fileName: string): string => {
      const ext = fileName.split('.').pop()?.toLowerCase();
      const map: Record<string, string> = {
        txt: 'text/plain',
        json: 'application/json',
        csv: 'text/csv',
        md: 'text/markdown',
        html: 'text/html',
        xml: 'text/xml',
        yaml: 'text/yaml',
        yml: 'text/yaml',
        log: 'text/plain',
        ts: 'text/typescript',
        js: 'text/javascript',
        py: 'text/x-python',
        sh: 'text/x-shellscript',
      };
      return map[ext ?? ''] ?? 'text/plain';
    };
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=false and destructiveHint=false, so the description adds context that the content is uploaded and delivered as a push. However, no further details on side effects, rate limits, or response behavior are provided. Given annotations already cover safety, this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no wasted words. It front-loads the core action and then provides context. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 4 parameters and no output schema, the description covers the main functionality and use cases. It could briefly mention what happens on success (e.g., device receives a notification with the file), but overall it is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter described. The description adds little beyond the schema, stating the general purpose but not providing additional semantic meaning or constraints for parameters like 'targetDeviceId' or 'title'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Send a text file to the user's device' uses a specific verb and resource, making the action unmistakable. It explicitly lists use cases (logs, reports, code snippets) and the method (file push), distinguishing it from siblings like zeph_notify or zeph_clipboard.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear guidance on when to use the tool: 'Use for logs, reports, code snippets, or any text content.' It does not explicitly state when not to use or name alternatives, but the context from use cases implies appropriate scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zeph-to/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server