Rename Symbol
curl --request POST \
--url https://api.example.com/tools/rename_symbolimport requests
url = "https://api.example.com/tools/rename_symbol"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/tools/rename_symbol', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/tools/rename_symbol",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/tools/rename_symbol"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/tools/rename_symbol")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/tools/rename_symbol")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"changes": {
"range": {
"start": {},
"end": {}
},
"newText": "<string>"
},
"totalEdits": 123,
"filesAffected": 123
}API Reference
Rename Symbol
Safely rename symbols across your entire project
POST
/
tools
/
rename_symbol
Rename Symbol
curl --request POST \
--url https://api.example.com/tools/rename_symbolimport requests
url = "https://api.example.com/tools/rename_symbol"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/tools/rename_symbol', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/tools/rename_symbol",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/tools/rename_symbol"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/tools/rename_symbol")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/tools/rename_symbol")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"changes": {
"range": {
"start": {},
"end": {}
},
"newText": "<string>"
},
"totalEdits": 123,
"filesAffected": 123
}Overview
Rename a Python symbol (function, class, variable, parameter, etc.) across your entire workspace. This tool finds all references and provides the exact text edits needed to rename safely.Request
string
required
File URI (e.g.,
file:///workspace/main.py)number
required
Line number where symbol appears (0-indexed)
number
required
Character position (0-indexed)
string
required
New name for the symbol
Response
object
number
Total number of edits across all files
number
Number of files that will be modified
Example Request
curl -X POST https://api.pylancemcp.dev/v1/tools/call \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "rename_symbol",
"arguments": {
"uri": "file:///workspace/app/utils.py",
"line": 8,
"character": 4,
"newName": "compute_total"
}
}'
from pylance_mcp import Client
client = Client(api_key="YOUR_API_KEY")
rename = client.rename_symbol(
uri="file:///workspace/app/utils.py",
line=8,
character=4,
new_name="compute_total"
)
print(f"Will modify {rename.files_affected} files")
print(f"Total edits: {rename.total_edits}")
# Apply the changes
for file_uri, edits in rename.changes.items():
print(f"\nFile: {file_uri}")
for edit in edits:
print(f" Line {edit.range.start.line}: '{edit.new_text}'")
import { PylanceMCP } from '@pylance-mcp/client';
const client = new PylanceMCP({ apiKey: 'YOUR_API_KEY' });
const rename = await client.renameSymbol({
uri: 'file:///workspace/app/utils.py',
line: 8,
character: 4,
newName: 'compute_total'
});
console.log(`Will modify ${rename.filesAffected} files`);
console.log(`Total edits: ${rename.totalEdits}`);
// Apply the changes
for (const [fileUri, edits] of Object.entries(rename.changes)) {
console.log(`\nFile: ${fileUri}`);
edits.forEach(edit => {
console.log(` Line ${edit.range.start.line}: '${edit.newText}'`);
});
}
import { PylanceMCP, RenameRequest } from '@pylance-mcp/client';
const client = new PylanceMCP({ apiKey: process.env.PYLANCE_API_KEY! });
const request: RenameRequest = {
uri: 'file:///workspace/app/utils.py',
line: 8,
character: 4,
newName: 'compute_total'
};
const rename = await client.renameSymbol(request);
console.log(`Will modify ${rename.filesAffected} files`);
console.log(`Total edits: ${rename.totalEdits}`);
// Apply the changes
for (const [fileUri, edits] of Object.entries(rename.changes)) {
console.log(`\nFile: ${fileUri}`);
edits.forEach(edit => {
console.log(` Line ${edit.range.start.line}: '${edit.newText}'`);
});
}
Example Response
{
"changes": {
"file:///workspace/app/utils.py": [
{
"range": {
"start": { "line": 8, "character": 4 },
"end": { "line": 8, "character": 19 }
},
"newText": "compute_total"
}
],
"file:///workspace/app/views.py": [
{
"range": {
"start": { "line": 42, "character": 12 },
"end": { "line": 42, "character": 27 }
},
"newText": "compute_total"
},
{
"range": {
"start": { "line": 87, "character": 8 },
"end": { "line": 87, "character": 23 }
},
"newText": "compute_total"
}
],
"file:///workspace/tests/test_utils.py": [
{
"range": {
"start": { "line": 15, "character": 16 },
"end": { "line": 15, "character": 31 }
},
"newText": "compute_total"
}
]
},
"totalEdits": 4,
"filesAffected": 3
}
Use Cases
Rename Function
# Original: calculate_total
def calculate_total(items: List[Item]) -> float:
return sum(item.price for item in items)
# Rename to: compute_total
# Result: All 47 references updated across 12 files
def compute_total(items: List[Item]) -> float:
return sum(item.price for item in items)
Rename Class
# Original: UserModel
class UserModel(BaseModel):
name: str
email: str
# Rename to: User
# Result: Class definition + all imports/usages updated
class User(BaseModel):
name: str
email: str
Rename Variable
# Original: temp_data
def process():
temp_data = fetch_data()
validate(temp_data)
return temp_data
# Rename to: user_data
# Result: All references in scope updated
def process():
user_data = fetch_data()
validate(user_data)
return user_data
Rename Parameter
# Original: x
def calculate(x: int, y: int) -> int:
return x + y
# Rename to: amount
# Result: Parameter + all references in function updated
def calculate(amount: int, y: int) -> int:
return amount + y
What Gets Renamed
Definition
The original symbol definition
All References
Every place the symbol is used
Imports
Import statements are updated
String Literals
Not renamed (only code references)
Safety Features
Scope-Aware: Only renames symbols in the same scope
Conflict Detection: Warns if new name conflicts with existing symbols
Atomic Operation: All files updated together or none at all
Preview First: Get all edits before applying
Applying Edits
The rename tool returns edits but doesn’t apply them automatically. You need to apply the changes:def apply_rename_edits(rename_result):
"""Apply rename edits to files."""
for file_uri, edits in rename_result.changes.items():
file_path = file_uri.replace('file://', '')
# Read file
with open(file_path, 'r') as f:
lines = f.readlines()
# Apply edits in reverse order (bottom to top)
# This prevents line number shifts
for edit in sorted(edits,
key=lambda e: e.range.start.line,
reverse=True):
start = edit.range.start
end = edit.range.end
# Get the line
line = lines[start.line]
# Replace the text
new_line = (
line[:start.character] +
edit.new_text +
line[end.character:]
)
lines[start.line] = new_line
# Write file
with open(file_path, 'w') as f:
f.writelines(lines)
# Use it
rename = client.rename_symbol(...)
apply_rename_edits(rename)
import fs from 'fs/promises';
async function applyRenameEdits(renameResult) {
for (const [fileUri, edits] of Object.entries(renameResult.changes)) {
const filePath = fileUri.replace('file://', '');
// Read file
const content = await fs.readFile(filePath, 'utf8');
const lines = content.split('\n');
// Apply edits in reverse order
const sortedEdits = edits.sort((a, b) =>
b.range.start.line - a.range.start.line
);
for (const edit of sortedEdits) {
const start = edit.range.start;
const end = edit.range.end;
const line = lines[start.line];
lines[start.line] =
line.substring(0, start.character) +
edit.newText +
line.substring(end.character);
}
// Write file
await fs.writeFile(filePath, lines.join('\n'));
}
}
// Use it
const rename = await client.renameSymbol(...);
await applyRenameEdits(rename);
Validation
Before renaming, the tool validates:| Check | Description |
|---|---|
| Symbol exists | Position must point to a valid symbol |
| Valid name | New name must be a valid Python identifier |
| No conflicts | New name doesn’t shadow existing symbols |
| Renameable | Symbol can be renamed (not a keyword) |
Error Responses
| Code | Reason | Solution |
|---|---|---|
INVALID_NAME | New name is not valid Python | Use valid identifier (letters, numbers, underscore) |
NAME_CONFLICT | New name already exists | Choose a different name |
NO_SYMBOL_FOUND | No symbol at position | Position cursor on a valid symbol |
CANNOT_RENAME | Symbol cannot be renamed | Built-in symbols can’t be renamed |
WORKSPACE_NOT_INDEXED | Workspace still indexing | Wait for indexing to complete |
Rate Limits
| Tier | Requests/Hour | Requests/Day |
|---|---|---|
| Free | 5 | 25 |
| Hobby | 100 | 1,000 |
| Pro | 1,000 | 10,000 |
| Enterprise | Unlimited | Unlimited |
Rename operations are expensive. Use sparingly and cache results.
Best Practices
Preview First: Always review the changes before applying them
Use Version Control: Commit before renaming so you can revert if needed
Test After: Run tests after renaming to catch any issues
Atomic Apply: Apply all edits at once, not file by file
Related Tools
Get References
Preview what will be renamed
Get Definition
Find the symbol’s definition
Apply Workspace Edit
Apply text edits to files
Get Diagnostics
Check for errors after renaming
Was this page helpful?
⌘I