> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pylancemcp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Read File

> Read the contents of a specific file in the workspace

## Overview

The `read-file` resource returns the full contents of a specific file in your workspace, along with metadata and encoding information.

## Resource URI

```
pylance://file/{path}
```

## Request

<ParamField path="uri" type="string" required>
  Resource URI with file path: `pylance://file/src/main.py`
</ParamField>

<ParamField query="encoding" type="string" default="utf-8">
  Character encoding (`utf-8`, `ascii`, `latin-1`, `utf-16`)
</ParamField>

<ParamField query="includeMetadata" type="boolean" default="true">
  Include file metadata in response
</ParamField>

<ParamField query="lineRange" type="object">
  Optional line range to read (e.g., `{"start": 10, "end": 50}`)
</ParamField>

## Response

<ResponseField name="content" type="string">
  Full file contents as string
</ResponseField>

<ResponseField name="path" type="string">
  Absolute file path
</ResponseField>

<ResponseField name="relativePath" type="string">
  Path relative to workspace root
</ResponseField>

<ResponseField name="metadata" type="object">
  File metadata (if `includeMetadata=true`)

  <Expandable title="Metadata Object">
    <ResponseField name="size" type="number">
      File size in bytes
    </ResponseField>

    <ResponseField name="lines" type="number">
      Number of lines in file
    </ResponseField>

    <ResponseField name="encoding" type="string">
      Detected character encoding
    </ResponseField>

    <ResponseField name="language" type="string">
      Language identifier (`python`, `python-stub`)
    </ResponseField>

    <ResponseField name="lastModified" type="string">
      ISO 8601 timestamp of last modification
    </ResponseField>

    <ResponseField name="hash" type="string">
      SHA-256 hash of file contents
    </ResponseField>
  </Expandable>
</ResponseField>

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pylancemcp.dev/v1/resources/read \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "uri": "pylance://file/src/models/user.py",
      "params": {
        "encoding": "utf-8",
        "includeMetadata": true
      }
    }'
  ```

  ```python Python theme={null}
  from pylance_mcp import MCPClient

  client = MCPClient(api_key="YOUR_API_KEY")

  file = client.read_resource(
      uri="pylance://file/src/models/user.py",
      encoding="utf-8",
      includeMetadata=True
  )

  print(file["content"])
  print(f"Lines: {file['metadata']['lines']}")
  print(f"Size: {file['metadata']['size']} bytes")
  ```

  ```javascript JavaScript theme={null}
  const { MCPClient } = require('@pylancemcp/client');

  const client = new MCPClient({ apiKey: 'YOUR_API_KEY' });

  const file = await client.readResource({
    uri: 'pylance://file/src/models/user.py',
    params: {
      encoding: 'utf-8',
      includeMetadata: true
    }
  });

  console.log(file.content);
  console.log(`Lines: ${file.metadata.lines}`);
  ```

  ```typescript TypeScript theme={null}
  import { MCPClient, FileResource } from '@pylancemcp/client';

  const client = new MCPClient({ apiKey: 'YOUR_API_KEY' });

  const file: FileResource = await client.readResource({
    uri: 'pylance://file/src/models/user.py',
    params: {
      encoding: 'utf-8',
      includeMetadata: true
    }
  });

  console.log(file.content);
  console.log(`Lines: ${file.metadata.lines}`);
  ```
</CodeGroup>

## Example Response

```json theme={null}
{
  "content": "from typing import Optional\nfrom datetime import datetime\n\nclass User:\n    \"\"\"User model representing a system user.\"\"\"\n    \n    def __init__(self, email: str, name: str):\n        self.email = email\n        self.name = name\n        self.created_at = datetime.now()\n    \n    def __repr__(self) -> str:\n        return f\"<User(email='{self.email}')>\"",
  "path": "/workspace/src/models/user.py",
  "relativePath": "src/models/user.py",
  "metadata": {
    "size": 342,
    "lines": 13,
    "encoding": "utf-8",
    "language": "python",
    "lastModified": "2025-12-16T15:20:00Z",
    "hash": "a3f5e8c9d2b1f4e7a6c8d9e2f1b3a4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1"
  }
}
```

## Reading Line Ranges

Read specific line ranges for large files:

```python theme={null}
# Read lines 50-100
file = client.read_resource(
    uri="pylance://file/src/large_file.py",
    lineRange={"start": 50, "end": 100}
)

print(file["content"])  # Only lines 50-100
print(f"Lines returned: {file['metadata']['linesReturned']}")
```

**Response:**

```json theme={null}
{
  "content": "# Lines 50-100 of the file...",
  "metadata": {
    "linesReturned": 51,
    "totalLines": 5000,
    "lineRange": {"start": 50, "end": 100}
  }
}
```

## Character Encodings

Supported encodings:

| Encoding  | Description       | Use Case            |
| --------- | ----------------- | ------------------- |
| `utf-8`   | Unicode (default) | Modern Python files |
| `ascii`   | ASCII only        | Legacy files        |
| `latin-1` | ISO-8859-1        | Western European    |
| `utf-16`  | Unicode 16-bit    | Windows files       |
| `cp1252`  | Windows-1252      | Windows legacy      |

<Info>
  Pylance automatically detects encoding from BOM (Byte Order Mark) and file headers. Specify encoding only if detection fails.
</Info>

## Common Use Cases

### Read Complete File

```python theme={null}
file = client.read_resource(uri="pylance://file/src/main.py")
content = file["content"]
```

### Read Large File in Chunks

```python theme={null}
chunk_size = 100
total_lines = 5000

for start in range(0, total_lines, chunk_size):
    chunk = client.read_resource(
        uri="pylance://file/src/large_file.py",
        lineRange={"start": start, "end": start + chunk_size}
    )
    process_chunk(chunk["content"])
```

### Get File Hash for Caching

```python theme={null}
file = client.read_resource(
    uri="pylance://file/src/models/user.py",
    includeMetadata=True
)

cache_key = file["metadata"]["hash"]
if cache_key in cache:
    content = cache[cache_key]
else:
    content = file["content"]
    cache[cache_key] = content
```

## Performance Considerations

<Warning>
  Files larger than 10MB will be automatically chunked. Use `lineRange` to read specific sections.
</Warning>

### Optimization Tips

<Check>Cache file contents using the SHA-256 hash</Check>
<Check>Use line ranges for large files (>1000 lines)</Check>
<Check>Disable metadata if not needed to reduce response size</Check>
<Check>Batch multiple file reads in parallel</Check>

**Example: Parallel Reads**

```python theme={null}
import asyncio

async def read_multiple_files(files):
    tasks = [
        client.read_resource_async(uri=f"pylance://file/{file}")
        for file in files
    ]
    return await asyncio.gather(*tasks)

files = ["src/main.py", "src/utils.py", "src/models.py"]
results = asyncio.run(read_multiple_files(files))
```

## Error Responses

<ResponseExample>
  ```json File Not Found theme={null}
  {
    "error": {
      "code": "FILE_NOT_FOUND",
      "message": "File does not exist",
      "details": {
        "path": "/workspace/src/missing.py",
        "workspaceRoot": "/workspace"
      }
    }
  }
  ```

  ```json Permission Denied theme={null}
  {
    "error": {
      "code": "PERMISSION_DENIED",
      "message": "Cannot read file outside workspace",
      "details": {
        "path": "/etc/passwd",
        "reason": "Path traversal attempt"
      }
    }
  }
  ```

  ```json Encoding Error theme={null}
  {
    "error": {
      "code": "ENCODING_ERROR",
      "message": "Failed to decode file",
      "details": {
        "path": "/workspace/src/binary.py",
        "requestedEncoding": "utf-8",
        "detectedEncoding": "binary"
      }
    }
  }
  ```

  ```json File Too Large theme={null}
  {
    "error": {
      "code": "FILE_TOO_LARGE",
      "message": "File exceeds size limit",
      "details": {
        "size": 52428800,
        "limit": 10485760,
        "suggestion": "Use lineRange parameter to read in chunks"
      }
    }
  }
  ```
</ResponseExample>

## Security

### Path Traversal Prevention

<Warning>
  All paths are validated to prevent directory traversal attacks. Attempts to access files outside the workspace will be rejected.
</Warning>

**Blocked Examples:**

```python theme={null}
# ❌ These will fail with PERMISSION_DENIED
client.read_resource(uri="pylance://file/../../../etc/passwd")
client.read_resource(uri="pylance://file//etc/hosts")
client.read_resource(uri="pylance://file/~/private_data.txt")
```

**Allowed Examples:**

```python theme={null}
# ✅ These will work (within workspace)
client.read_resource(uri="pylance://file/src/main.py")
client.read_resource(uri="pylance://file/src/../utils/helpers.py")  # Resolves to src/utils/helpers.py
client.read_resource(uri="pylance://file/./src/main.py")  # Resolves to src/main.py
```

## Rate Limits

| Tier       | Requests/Day | Max File Size |
| ---------- | ------------ | ------------- |
| Free       | 100          | 1 MB          |
| Hobby      | 5,000        | 5 MB          |
| Pro        | 50,000       | 10 MB         |
| Enterprise | Unlimited    | 50 MB         |

## Related Resources

<CardGroup cols={2}>
  <Card title="List Files" icon="list" href="/api-reference/resources/list-files">
    Get all files in workspace
  </Card>

  <Card title="Workspace Structure" icon="folder-tree" href="/api-reference/resources/workspace-structure">
    View project hierarchy
  </Card>
</CardGroup>
